二叉樹 先、中、後序遞歸和非遞歸遍歷

今天自己寫了下 二叉樹的遍歷, 練練手哈哈.  

Java代碼如下:

package Tree;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class BTreeTraverse {
	public static void main(String[] args) {
		binaryTree tree = new binaryTree();
		tree.insertNode(4);
		tree.insertNode(3);
		tree.insertNode(2);
		tree.insertNode(1);
		tree.insertNode(3);
		tree.insertNode(5);
		tree.insertNode(7);
		tree.insertNode(6);
		Node<Integer> root = tree.getRoot();
		System.out.println("breadth");
		tree.breadthFirstTraverse(tree.getRoot());
		System.out.println();
		System.out.println("preOrder");
		tree.preOrderTraverse(tree.getRoot());
		System.out.println();
		System.out.println("preOderNocursor");
		tree.preOrderTraverseNoRecursion(tree.getRoot());
		System.out.println();
		System.out.println("midOrder");		
		tree.midOrderTraverse(tree.getRoot());
		System.out.println();
		System.out.println("midOderNocursor");
		tree.midOrderTraverseNoRecursion(tree.getRoot());
		System.out.println();
		System.out.println("postOrder");		
		tree.postOrderTraverse(tree.getRoot());
		System.out.println();
		System.out.println("postOderNocursor");			
		tree.postOrderTraverseNoRecursion(tree.getRoot());
		System.out.println();
		System.out.println("postOderNocursor2");
		tree.postOrderTraverseNoRecursion2(tree.getRoot());
		System.out.println();		
		System.out.println("end---");	

	}
	

	static class Node<E extends Comparable<E>>{
		E value;
		Node<E> left;
		Node<E> right;
		Node(E value){
			this.value = value;
		}
	}
	
	static class binaryTree<E extends Comparable<E>>{
		private Node <E> root ;
		public binaryTree() {
			// TODO Auto-generated constructor stub
			root = null;
		}
		public Node<E> getRoot(){
			return this.root;
		}
		public void insertNode(E value){
			if(root == null){
				root = new Node<E>(value);
				return;
			}
			
			Node<E> currentNode = root;
			
			while(true){
				if(value.compareTo(currentNode.value) < 0){
					if(currentNode.left == null){
							currentNode.left = new Node<E>(value);
							return;
						}
					currentNode = currentNode.left;
				}
				else{
					if(currentNode.right == null){
						currentNode.right = new Node<E>(value);
						return;
					}
					currentNode = currentNode.right;
				}
			}
		}
		//廣度優先遍歷
		public void breadthFirstTraverse(Node<E> root){
			if(root == null){
				System.out.println("BTree is empty");
				return;
			}
			Queue<Node<E>> queue = new LinkedList<Node<E>>();
			Node<E> currentNode;
			queue.add(root);
			while(!queue.isEmpty()){
				currentNode = queue.poll();
				System.out.print(currentNode.value + " ");
				if(currentNode.left != null)
					queue.add(currentNode.left);
				if(currentNode.right != null)
					queue.add(currentNode.right);				
			}
		}
		//先序遍歷   遞歸
		public void preOrderTraverse(Node<E> root) {
			System.out.print(root.value + " ");
			if (root.left != null) 
				preOrderTraverse(root.left);
			if(root.right != null)
				preOrderTraverse(root.right);
			
		}
		//先序   非遞歸
		public void preOrderTraverseNoRecursion(Node<E> root) {
			Stack<Node<E>> stack = new Stack<Node<E>>();
			if(root!=null)
				stack.push(root);
			Node<E> currentNode;
			while(!stack.isEmpty()){
				currentNode = stack.pop();
				System.out.print(currentNode.value+" ");
				if(currentNode.right != null)
					stack.push(currentNode.right); //右節點先入後出
				if(currentNode.left != null)
					stack.push(currentNode.left);
			}
		}
		//中序 遞歸
		public void midOrderTraverse(Node<E> root){
			if(root.left != null)
				midOrderTraverse(root.left);
			System.out.print(root.value+" ");
			if(root.right != null)
				midOrderTraverse(root.right);
		}
		//中序 非遞歸
		public void midOrderTraverseNoRecursion(Node<E> root) {
			Stack<Node<E>> stack = new Stack<Node<E>>();
			//stack.push(root);
			Node<E> currentNode = root;
			while(currentNode!=null || !stack.isEmpty()){
				//currentNode = stack.peek();
				if (currentNode != null) {
					stack.push(currentNode);
					currentNode = currentNode.left;					
				}else{
					currentNode = stack.pop();
					System.out.print(currentNode.value+" ");
					currentNode = currentNode.right;
				}
			}
			
		}
		//後序   遞歸
		public void postOrderTraverse(Node<E> root){
			if(root.left != null)
				postOrderTraverse(root.left);
			if(root.right != null)
				postOrderTraverse(root.right);
			System.out.print(root.value + " ");
		}
		//後序  非遞歸(我認爲最難想的一個) 方法一
		public void postOrderTraverseNoRecursion(Node<E> root){
			Stack<Node<E>> stack = new Stack<Node<E>>();
			Stack<Node<E>> output = new Stack<Node<E>>();
			
			Node<E> currentNode = root;			
			while(currentNode !=null || !stack.isEmpty()){				
				if(currentNode != null){
					stack.push(currentNode);
					output.push(currentNode);
					currentNode = currentNode.right;
				}else{
					currentNode = stack.pop();
					currentNode = currentNode.left;
				}
			}
			while(!output.isEmpty()){
				System.out.print(output.pop().value+" ");
			}
		}
		//後序遍歷  非遞歸  方法2
		public void postOrderTraverseNoRecursion2(Node<E> root) {
			//根->右->左  遍歷,將輸出保存在棧中,然後輸出(可以這麼理解啦  *****
			Stack<Node<E>> stack = new Stack<Node<E>>();
			Stack<Node<E>> output = new Stack<Node<E>>();
			Node<E> currentNode = root;
			if(root != null){
				stack.push(root);
			}
			while(!stack.empty()){
				currentNode = stack.pop();
				output.push(currentNode);
				if(currentNode.left!=null){
					stack.push(currentNode.left);
				}
				if(currentNode.right != null){
					stack.push(currentNode.right);
				}
			}
			while(!output.isEmpty()){
				System.out.print(output.pop().value+" ");
			}
		}	
	}
}


另外時間複雜度O(n),空間複雜度O(1)的Morris 遍歷,大家可以在網上找到很多資料。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章