链表

注意:在使用链表进行操作时,有关头结点需要注意的是,不能轻易使用头节点进行数据的操作,不然在下次想遍历链表的时候,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;
		}
	}

 

 

如有问题,敬请指出,与君共勉。参考《程序员面试手册》