链表
注意:在使用链表进行操作时,有关头结点需要注意的是,不能轻易使用头节点进行数据的操作,不然在下次想遍历链表的时候,head指针需要指向链表的头,除非是不在使用从头遍历节点。
⑴使用链表实现栈
public void push(ListNode head,ListNode newNode) {
newNode.next = head;
head = newNode;
}
public void pop(ListNode head) {
ListNode temp = head.next;
head = temp;
}
⑵寻找链表的倒数第n个节点
public ListNode findElement(ListNode head,int number) {
if(head == null) return;
ListNode temp = head,nNode = head;
while(number !=0) {
temp = temp.next;
number --;
}
while(temp.next != null) {
nNode = nNode.next;
temp = temp.next;
}
return nNode;
}
⑶判断一个链表是否以NULL结尾的链表还是一个包含循环的链表?
public boolean IsLinkedListContainsLoop(ListNode head) {
ListNode slow = head,fast = head;
while(slow !=null && fast!= null && fast.next != null) {
slow =slow.next;
fast = fast.next。next;
if(slow == fast) {
return true;
}
}
return false;
}
⑷在排序后的链表中插入元素?
public ListNode Insert(ListNode head,ListNode newNode) {
ListNode current = head ,temp = null;
while(current!= null && current.data < newNode.data) {
temp = current;
current = current.next;
}
newNode.next = current;
temp.next = newNode;
return head;
}
⑸使用单个链表构建节点顺序相反的另一个链表?
public ListNode reverse(ListNode head) {
ListNode temp = null,nextNode = null;
while(head != null) {
nextNode = head.next;
head.next = temp;
temp = head;
head = nextNode;
}
return temp;
}
⑹逆向展示链表
public void PrintList(ListNode head) {
if(head != null)
return;
PrintList(head.next);
System.out.println(head.data);
}
⑺判断链表总节点数的奇偶
public int isLinkedEven(ListNode head) {
while(head!= null && head.next!= null)
head = head.next.next;
if(head!= null)
return 0;
return 1;
}
⑻合并链表
public ListNode merger(ListNode head1,ListNode head2) {
ListNode result ;
if(head1 == null)
return head2;
if(head2 == null)
return head1;
if(head1.data<=head2.data) {
result = head1;
result.next = merger(head1.next,head2);
}else {
result = head2;
result.next = merger(head2.next,head1);
}
return result;
}
public ListNode merger2(ListNode head1,ListNode head2) {
ListNode newNode = new ListNode() ,temp;
newNode.next = null;
temp = newNode;
while(head1 !=null && head2 != null) {
if(head1.data<head2.data) {
temp.next = head1;
temp = temp.next;
head1 = head1.next;
}else {
temp.next = head2;
temp = temp.next;
head2 = head2.next;
}
}
if(head1!=null)
temp.next = head1;
else
temp.next = head2;
temp = newNode.next;
return temp;
}
⑼以2为单位,对链表的元素进行对调
public ListNode Nreverse(ListNode head) {
ListNode temp1=null,temp2=null,current= head;
while(current != null && current.next != null) {
if(temp1 != null) {
temp1.next.next = current.next;
}
temp1 = current.next;
current.next = current.next.next;
temp1.next = current;
if(temp2 == null)
temp2 = temp1;
current = current.next;
}
return temp2;
}
栈
使用数组实现栈的初始化,出栈和入站,以及删除栈。优点是:执行出栈入栈的效率很高,时间复杂度为O(1),缺点是:栈的容量是使用数组,而数组的内存大小是提前设置好的,不能再改变,当栈中数据满了,会发生异常。也可以使用动态数组和链表的方式来实现栈。
class ArrayStack{
int top;
int capacity;
int[] array;
}
ArrayStack createStack() {
ArrayStack stack = new ArrayStack();
stack.top = -1;
stack.capacity=1;
stack.array = new int [stack.capacity];
return stack;
}
boolean isEmpty(ArrayStack stack) {
return (stack.top == -1);
}
boolean isFull(ArrayStack stack) {
return (stack.top == stack.capacity-1);
}
void push(ArrayStack stack,int data) {
if(isFull(stack))
System.out.println("stack overflow");
else
stack.array[++stack.top] =data;
}
int pop(ArrayStack stack) {
if(isEmpty(stack)) {
System.out.println("error");
return 0;
}else{
return stack.array[stack.top--];
}
}
void deleteStack(ArrayStack stack) {
if(stack != null) {
stack.top=-1;
stack.array = null;
}
}
⑴给出字符串,反复移除其中邻接且相同的字符,直到不含有这样的字符为止。
void removeadjacent(char [] str) {
int stkptr = 1;
int i = 0;
int len = str.length;
while(i<len) {
if(stkptr == -1 || str[stkptr] != str[i]) {
stkptr++;
str[stkptr] = str[i];
i++;
}else {
while(i < len && str[stkptr] == str[i])
i++;
stkptr--;
}
}
str[stkptr+1]='\0';
}
队列
是一种先进先出的数据结构,队列的实现可以是简单的循环数组,动态的循环数组,链表。
使用数组进行队列的创建,增,删,出列,入列
class ArrayQueue{
int front,rear;
int capacity;
int [] array ;
}
ArrayQueue createQueue(int size) {
ArrayQueue aq = new ArrayQueue();
if(aq!=null)
return null;
aq.capacity = size;
aq.front = aq.rear = -1;
aq.array = new int[aq.capacity];
return aq;
}
boolean isEmpty(ArrayQueue queue) {
return (queue.front == -1);
}
boolean isFull(ArrayQueue queue) {
return ((queue.rear +1 ) % queue.capacity == queue.front);
}
int size(ArrayQueue queue) {
if(queue.front == -1)
return 0;
int size = queue.rear - queue.front + 1;
return size < 0 ? size + queue.capacity : size;
}
void Enqueue(ArrayQueue queue,int data) {
if(isFull(queue))
System.out.println("error");
else {
queue.rear =(queue.rear+1)%queue.capacity;
queue.array[queue.rear] = data;
if(queue.front == -1)
queue.front = queue.rear;
}
}
int Dequeue(ArrayQueue queue) {
int data = 0;
if(isEmpty(queue)) {
System.out.println("error");
return 0;
}else {
data = queue.array[queue.front];
if(queue.front == queue.rear)
queue.front =queue.rear =-1;
else
queue.front = (queue.front+1)% queue.capacity;
}
return data;
}
void Deletequeue(ArrayQueue queue) {
if(queue!=null) {
if(queue.array !=null)
queue.array =null;
}
}
⑴使用两个栈来模拟队列
ArrayStack stack1 =createStack();
ArrayStack stack2 =createStack();
boolean Enqueue(int value) {
push(stack1,value);
return true;
}
boolean Dequeue() {
int data;
if(!isEmpty(stack2)) {
data = stack2.top;
pop(stack2);
return true;
}
while(!isEmpty(stack1)) {
data = stack1.top;
pop(stack1);
push(stack2, data);
}
if(isEmpty(stack2))
return false;
data = pop(stack2);
pop(stack2);
return true;
}
树
树一种非线性的数据结构,它的每个节点指向多个节点。树的分类有:二叉树,泛化树,线索二叉树,二叉搜索树,平衡树,红黑树,B+树,B-树,基本概念和定义不做介绍。有关树的遍历在以前的文章中有涉及。
⑴寻找二叉树中的最大元素
int findMaxElement(BinaryTreeNode root) {
int root_val,left,right,max = Integer.MIN_VALUE;
if(root != null) {
root_val = root.data;
left = findMaxElement(root.left);
right = findMaxElement(root.right);
if(left > right)
max = left;
else
max = right;
if(root_val > max)
max = root_val;
}
return max;
}
int findMaxElement2(BinaryTreeNode root) {
BinaryTreeNode temp;
int max= Integer.MIN_VALUE;
Queue<BinaryTreeNode> queue = new ArrayDeque<BinaryTreeNode>();
queue.add(root);
while(!queue.isEmpty()) {
temp = queue.poll();
if(max < temp.data)
max = temp.data;
if(temp.left != null)
queue.add(temp.left);
if(temp.right != null)
queue.add(temp.right);
}
return max;
}
⑵在二叉树的任意空位置插入元素
void insertElement (BinaryTreeNode root,int data) {
Queue<BinaryTreeNode> queue = new ArrayDeque<BinaryTreeNode>();
BinaryTreeNode temp ;
BinaryTreeNode newNode = new BinaryTreeNode();
newNode.left = newNode.right = null;
newNode.data = data;
if(root == null) {
root = newNode;
return ;
}
queue.add(root);
while(!queue.isEmpty()) {
temp = queue.poll();
if(temp.left == null) {
temp.left = newNode;
return;
}else
queue.add(temp.left);
if(temp.right == null) {
temp.right = newNode;
return ;
}else
queue.add(temp.right);
}
}
⑶求二叉树的大小
int SizeofTree(BinaryTreeNode root) {
if(root == null)
return 0;
else
return (SizeofTree(root.left) + 1 + SizeofTree(root.right));
}
int SizeOfTree(BinaryTreeNode root) {
if(root == null) return 0;
Queue<BinaryTreeNode> queue = new ArrayDeque<BinaryTreeNode>();
BinaryTreeNode temp ;
queue.add(root);
int count = 0;
while(!queue.isEmpty()) {
temp = queue.poll();
count++;
if(temp.left != null)
queue.add(temp.left);
if(temp.right != null)
queue.add(temp.right);
}
return count;
}
⑷由下到上分层遍历二叉树
void levelTraversal(BinaryTreeNode root) {
if(root == null) return ;
Queue<BinaryTreeNode> queue = new ArrayDeque<BinaryTreeNode>();
BinaryTreeNode temp;
queue.add(root);
Stack<BinaryTreeNode> stack = new Stack<BinaryTreeNode>();
while(!queue.isEmpty()) {
temp = queue.poll();
stack.push(temp);
if(temp.right != null)
queue.add(temp.right);
if(temp.left != null)
queue.add(temp.left);
}
while(!stack.isEmpty()) {
System.out.println(stack.pop());
}
}
⑸求二叉树的高度
int heightOfBinaryTreeNode(BinaryTreeNode root) {
int left,right;
if(root == null)
return 0;
else {
left = heightOfBinaryTreeNode(root.left);
right =heightOfBinaryTreeNode(root.right);
if(left > right)
return left+1;
else
return right+1;
}
}
int heightOfBinaryTreeNode2(BinaryTreeNode root) {
if(root == null) return 0;
Queue<BinaryTreeNode> queue = new ArrayDeque<BinaryTreeNode>();
BinaryTreeNode temp ;
queue.add(root);
queue.add(null);
int level = 0;
while(!queue.isEmpty()) {
temp = queue.poll();
if(temp == null) {
if(!queue.isEmpty())
queue.add(null);
level++;
}else {
if(temp.left != null)
queue.add(temp.left);
if(temp.right != null)
queue.add(temp.right);
}
}
return level;
}
⑹删除二叉树中最深的节点
BinaryTreeNode findMaxPathNode(BinaryTreeNode root) {
if(root == null ) return null;
Queue<BinaryTreeNode> queue = new ArrayDeque<BinaryTreeNode>();
BinaryTreeNode temp ;
queue.add(root);
while(!queue.isEmpty()) {
temp = queue.poll();
if(temp.left != null)
queue.add(temp.left);
if(temp.right != null)
queue.add(temp.right);
}
return temp;
}
BinaryTreeNode findTrageNode (BinaryTreeNode root,int data) {
if(root == null) return null;
if(root.data == data)
return root;
findTrageNode(root.left,data);
findTrageNode(root.right, data);
}
void DeleteOfBinaryTreeNode(BinaryTreeNode root,int data) {
BinaryTreeNode target = findTrageNode(root,data);
BinaryTreeNode MaxDeepNode = findMaxPathNode(root);
target = MaxDeepNode;
MaxDeepNode = null;
}
⑺判断两颗二叉树在结构上是否相同
boolean IsEqual(BinaryTreeNode root1,BinaryTreeNode root2) {
if(root1 == null && root2 == null)
return true;
if(root1 == null || root2 == null)
return false;
if(root1.data == root2.data)
return true;
return IsEqual(root1.left, root2.left) && IsEqual(root1.right,root2.right);
}
⑻根节点到每一个叶节点的路径分别打印出来
void PrintPath(BinaryTreeNode root,int path[],int length) {
if(root == null) return ;
path[length] = root.data;
length++;
if(root.left == null && root.right == null)
PrintArray(path,length);
else {
PrintPath(root.left, path, length);
PrintPath(root.right, path, length);
}
}
void PrintArray(int[] array,int len) {
for(int i = 0 ;i< len; i++)
System.out.println(array[i]);
}
⑼打印出二叉树中某节点的所有祖先
boolean PrintAncestor(BinaryTreeNode root,BinaryTreeNode node) {
if(root == null)
return false;
if(root.left == node ||
root.right == node ||
PrintAncestor(root.left, node) ||
PrintAncestor(root.right, node)) {
System.out.println(root.data);
return true;
}
return false;
}
⑽在二叉搜索树中搜索某个元素
BinaryTreeNode find(BinaryTreeNode root,int data) {
if(root == null)
return null;
if(data > root.data)
return find(root.right,data);
else if(data < root.data)
return find(root.left,data);
return root;
}
BinaryTreeNode find2(BinaryTreeNode root,int data) {
if(root == null) return null;
while(root!=null) {
if(root.data > data)
root = root.right;
else if(root.data < data)
root = root.left;
else
return root;
}
return null;
}
}
如有问题,敬请指出,与君共勉。参考《程序员面试手册》