二叉樹的遞歸,非遞歸遍歷,深度優先遍歷,廣度優先遍歷

/**
 * 二叉樹的定義和遍歷
 */
public class BinaryTree {
	/**
	 * 打印節點的信息
	 */
	public void printNode(TreeNode<String> node){
		System.out.print(node.getData()+"  ");
	}
    /**
     * 遞歸先序遍歷二叉樹
     */
    public void preIterator(TreeNode<String> node){
    	this.printNode(node);
    	if (node.getLefNode() != null) {
			this.preIterator(node.getLefNode());
		}
    	if (node.getRigNode() != null) {
			this.preIterator(node.getRigNode());
		}
    }
    /**
     * 遞歸中序遍歷二叉樹
     */
    public void midIterator(TreeNode<String> node){
    	if (node.getLefNode() != null) {
			midIterator(node.getLefNode());
		}
    	this.printNode(node);
    	if (node.getRigNode() != null) {
			midIterator(node.getRigNode());
		}
    }
    /**
     * 遞歸後續遍歷二叉樹
     */
    public void lasIterator(TreeNode<String> node){
    	if (node.getLefNode() != null) {
			this.lasIterator(node.getLefNode());
		}
    	if (node.getRigNode() != null) {
			this.lasIterator(node.getRigNode());
		}
    	this.printNode(node);
    }
    /**
     * 非遞歸先序遍歷二叉樹
     * @return
     */
    public void  noDiGuiPreIterator(TreeNode<String> node) {
		Stack<TreeNode<String>> stack = new Stack<>();
		TreeNode<String> p = node;
		while (p != null || stack.size() > 0) {
			while(p != null){
				//壓入全部的左節點,壓入前訪問它。左節點壓入完後pop訪問右節點。
				this.printNode(p);
				stack.push(p);
				p = p.getLefNode();
			}
			if(stack.size() > 0){
				p = stack.pop();
				p = p.getRigNode();
			}
		}
    }  
    /**
     * 非遞歸中序遍歷二叉樹
     * @return
     */
    public void noDiGuiMidIterator(TreeNode<String> node){
    	Stack<TreeNode<String>> stack = new Stack<>();
		TreeNode<String> p = node;
		while (p != null || stack.size() > 0) {
			while(p != null){
				stack.push(p);
				p = p.getLefNode();
			}
			if(stack.size() > 0){
				p = stack.pop();
				this.printNode(p);
				p = p.getRigNode();
			}
		}
    }

    /**
     * 非遞歸後續遍歷二叉樹
     * @return
     */
    public void noDiGuiLasIterator(TreeNode<String> node){
    	Stack<TreeNode<String>> stack = new Stack<>();    
    	TreeNode<String> p = node;
    	TreeNode<String> prev = node;    
        while (p != null || stack.size() > 0) {    
            while (p != null) {    
                stack.push(p);    
                p = p.getLefNode();    
            }    
            if (stack.size() > 0) {    
            	TreeNode<String> temp = stack.peek().getRigNode();    
                if (temp == null || temp == prev) {    
                    p = stack.pop();    
                   this.printNode(p);  
                    prev = p;    
                    p = null;    
                } else {    
                    p = temp;    
                }    
            } 
        }
    }
    
    /**
     * 不只是二叉樹,其餘的多叉數也適合
     * 深度優先遍歷
     */
    public void depthOrderTraversal(TreeNode<String> node){
        Stack<TreeNode<String>> stack=new Stack<>();
        if (node != null){
        	stack.push(node);       
		}
        while(stack.isEmpty()==false){
        	TreeNode<String> p = stack.pop();
            this.printNode(p);
            //棧是後進先出,由於先遍歷左節點,全部左節點要後添加,即先添加右節點。
            if(p.getRigNode() != null){
                stack.push(p.getRigNode());
            }
            if(p.getLefNode() != null){
                stack.push(p.getLefNode());
            }           
        }
        System.out.print("\n");
    }
    /**
     * 不只適合二叉樹,也適合其餘的多叉樹
     * 廣度優先遍歷
     */
    public void levelOrderTraversal(TreeNode<String> node){
        Queue<TreeNode<String>> queue=new ArrayDeque<>();
        queue.add(node);
        while(queue.isEmpty()==false){
        	TreeNode<String> p = queue.remove();
        	this.printNode(p);
        	//隊列是先進先出,全部先放左子樹,先遍歷左邊的節點
        	if(p.getLefNode() != null){
                queue.add(p.getLefNode());
            }
            if(p.getRigNode() != null){
                queue.add(p.getRigNode());
            }
        }
    }
    // 初始化二叉樹  
    public TreeNode<String> init() {  
        TreeNode<String> D = new TreeNode<String>("D", null, null);  
        TreeNode<String> H = new TreeNode<String>("H", null, null);  
        TreeNode<String> I = new TreeNode<String>("I", null, null);  
        TreeNode<String> J = new TreeNode<String>("J", null, null);  
        TreeNode<String> P = new TreeNode<String>("P", null, null);  
        TreeNode<String> G = new TreeNode<String>("G", P, null);  
        TreeNode<String> F = new TreeNode<String>("F", null, J);  
        TreeNode<String> E = new TreeNode<String>("E", H, I);  
        TreeNode<String> B = new TreeNode<String>("B", D, E);  
        TreeNode<String> C = new TreeNode<String>("C", F, G);  
        TreeNode<String> A = new TreeNode<String>("A", B, C);  
        return A;  
    } 
   /**
    * 測試
    * @param args
    */
    public static void main(String[] args) {
		BinaryTree binaryTree = new BinaryTree();
		TreeNode<String> node = binaryTree.init();
		
		System.out.println("二叉樹的遞歸先序遍歷");
		binaryTree.preIterator(node);
		System.out.println("\n二叉樹的非遞歸先序遍歷");
		binaryTree.noDiGuiPreIterator(node);
		
		System.out.println("\n二叉樹的遞歸中序遍歷");
		binaryTree.midIterator(node);
		System.out.println("\n二叉樹的非遞歸中序遍歷");
		binaryTree.noDiGuiMidIterator(node);
		
		System.out.println("\n二叉樹的遞歸後序遍歷");
		binaryTree.lasIterator(node);
		System.out.println("\n二叉樹的非遞歸後序遍歷");
		binaryTree.noDiGuiLasIterator(node);

		System.out.println("\n數的深度優先遍歷");
		binaryTree.depthOrderTraversal(node);

		System.out.println("\n數的廣度優先遍歷");
		binaryTree.levelOrderTraversal(node);
    }
}

/**
 * 定義節點
 */
class TreeNode<T>{
	
	private T data;
	private TreeNode<T> lefNode;
	private TreeNode<T> rigNode;
	
	public TreeNode(T data, TreeNode<T> lefNode, TreeNode<T> rigNode) {
		super();
		this.data = data;
		this.lefNode = lefNode;
		this.rigNode = rigNode;
	}
	public T getData() {
		return data;
	}
	public void setData(T data) {
		this.data = data;
	}
	public TreeNode<T> getLefNode() {
		return lefNode;
	}
	public void setLefNode(TreeNode<T> lefNode) {
		this.lefNode = lefNode;
	}
	public TreeNode<T> getRigNode() {
		return rigNode;
	}
	public void setRigNode(TreeNode<T> rigNode) {
		this.rigNode = rigNode;
	}
}

結果:java

二叉樹的遞歸先序遍歷
A  B  D  E  H  I  C  F  J  G  P  
二叉樹的非遞歸先序遍歷
A  B  D  E  H  I  C  F  J  G  P  
二叉樹的遞歸中序遍歷
D  B  H  E  I  A  F  J  C  P  G  
二叉樹的非遞歸中序遍歷
D  B  H  E  I  A  F  J  C  P  G  
二叉樹的遞歸後序遍歷
D  H  I  E  B  J  F  P  G  C  A  
二叉樹的非遞歸後序遍歷
D  H  I  E  B  J  F  P  G  C  A  
數的深度優先遍歷
A  B  D  E  H  I  C  F  J  G  P  node

數的廣度優先遍歷
A  B  C  D  E  F  G  H  I  J  P  測試

相關文章
相關標籤/搜索