二叉樹的前序、中序、後序遍歷

遞歸方式:

  1. /** 
  2.  * 實現二叉樹的創建、前序遍歷、中序遍歷和後序遍歷 
  3.  **/  
  4. package DataStructure;  
  5.   
  6. /** 
  7.  * Copyright 2014 by Ruiqin Sun 
  8.  * All right reserved 
  9.  * created  on 2014-9-9 下午2:34:15 
  10.  **/  
  11. public class BinTreeInt {  
  12.     private Node root;  
  13.       
  14.     /** 
  15.      * 創建內部節點類 
  16.      **/  
  17.     private class Node{  
  18. //      左節點  
  19.         private Node leftChild;  
  20. //      右節點  
  21.         private Node rightChild;  
  22. //      節點對應的值  
  23.         private int data;  
  24.           
  25.         public Node(int data){  
  26.             this.leftChild = null;  
  27.             this.rightChild = null;  
  28.             this.data = data;  
  29.         }  
  30.     }// class Node  
  31.       
  32.     public BinTreeInt(){  
  33.         root = null;  
  34.     }  
  35.       
  36.     /* 
  37.      *遞歸的創建二叉樹 
  38.      * */  
  39.     public void buildTree(Node node ,int data){  
  40.         if (root == null){// 如果根節點爲空,創建根節點  
  41.             root = new Node(data);  
  42.         }else{  
  43.             if(data <node.data){//插入到左子樹  
  44.                 if(node.leftChild == null){//左節點爲空,直接創建值爲data的左節點  
  45.                     node.leftChild = new Node(data);  
  46.                 }else{//左節點不爲空,調用buildTree函數插到左子樹中  
  47.                     buildTree(node.leftChild,data);  
  48.                 }  
  49.             }else{  
  50.                 if(node.rightChild == null){  
  51.                     node.rightChild = new Node(data);  
  52.                 }else{  
  53.                     buildTree(node.rightChild,data);  
  54.                 }  
  55.             }         
  56.         }  
  57.     }//end buildTree  
  58.     /* 
  59.      *前序遍歷二叉樹 
  60.      * */  
  61.     public void preOrder(Node node){  
  62.         if(node != null){  
  63.             System.out.print(node.data);  
  64.             preOrder(node.leftChild);  
  65.             preOrder(node.rightChild);  
  66.         }  
  67.     }  
  68.     /* 
  69.      *中序遍歷二叉樹 
  70.      * */  
  71.     public void inOrder(Node node){  
  72.         if(node != null){  
  73.             inOrder(node.leftChild);  
  74.             System.out.print(node.data);  
  75.             inOrder(node.rightChild);  
  76.         }  
  77.     }  
  78.     /* 
  79.      *後序遍歷二叉樹 
  80.      * */  
  81.     public void postOrder(Node node){  
  82.         if(node != null){  
  83.             postOrder(node.leftChild);  
  84.             postOrder(node.rightChild);  
  85.             System.out.print(node.data);              
  86.         }  
  87.     }  
  88.       
  89.     public static void main(String ars[]){  
  90.         int[] a={2,4,12,45,21,6,111};  
  91.         BinTreeInt binTree = new BinTreeInt();  
  92.         for(int i = 0; i<a.length; i++){  
  93.             binTree.buildTree(binTree.root, a[i]);  
  94.         }  
  95.         System.out.print("前序遍歷");  
  96.         binTree.preOrder(binTree.root);  
  97.         System.out.println("");  
  98.         System.out.print("中序遍歷");  
  99.         binTree.inOrder(binTree.root);  
  100.         System.out.println("");  
  101.         System.out.print("後序遍歷");  
  102.         binTree.postOrder(binTree.root);  
  103.     }  
  104. }  


棧的實現:

  1. /** 
  2.  *  
  3.  * @author kerryfish 
  4.  * JAVA實現二叉樹的先序、中序、後序、層序遍歷 
  5.  * 遞歸和非遞歸版本 
  6.  * 
  7.  */  
  8.   
  9. class Node{  
  10.     public int value;  
  11.     public Node left;  
  12.     public Node right;  
  13.     public Node(int v){  
  14.         this.value=v;  
  15.         this.left=null;  
  16.         this.right=null;  
  17.     }  
  18.       
  19. }  
  20. class BinaryTreeTraversal { 
  21.     /** 
  22.      *  
  23.      * @param root 樹根節點 
  24.      * 利用棧實現循環先序遍歷二叉樹 
  25.      * 這種實現類似於圖的深度優先遍歷(DFS) 
  26.      * 維護一個棧,將根節點入棧,然後只要棧不爲空,出棧並訪問,接着依次將訪問節點的右節點、左節點入棧。 
  27.      * 這種方式應該是對先序遍歷的一種特殊實現(看上去簡單明瞭),但是不具備很好的擴展性,在中序和後序方式中不適用 
  28.      */  
  29.     public static void preOrderStack_1(Node root){  
  30.         if(root==null)return;  
  31.         Stack<Node> s=new Stack<Node>();  
  32.         s.push(root);  
  33.         while(!s.isEmpty()){  
  34.             Node temp=s.pop();  
  35.             System.out.println(temp.value);  
  36.             if(temp.right!=null) s.push(temp.right);  
  37.             if(temp.left!=null) s.push(temp.left);  
  38.         }  
  39.     }  
  40.     /** 
  41.      *  
  42.      * @param root 樹的根節點 
  43.      * 利用棧模擬遞歸過程實現循環先序遍歷二叉樹 
  44.      * 這種方式具備擴展性,它模擬遞歸的過程,將左子樹點不斷的壓入棧,直到null,然後處理棧頂節點的右子樹 
  45.      */  
  46.     public static void preOrderStack_2(Node root){  
  47.         if(root==null)return;  
  48.         Stack<Node> s=new Stack<Node>();  
  49.         while(root!=null||!s.isEmpty()){  
  50.             while(root!=null){  
  51.                 System.out.println(root.value);  
  52.                 s.push(root);//先訪問再入棧  
  53.                 root=root.left;  
  54.             }  
  55.             root=s.pop();  
  56.             root=root.right;//如果是null,出棧並處理右子樹  
  57.         }  
  58.     }  
  59.     /** 
  60.      *  
  61.      * @param root 樹根節點 
  62.      * 利用棧模擬遞歸過程實現循環中序遍歷二叉樹 
  63.      * 思想和上面的preOrderStack_2相同,只是訪問的時間是在左子樹都處理完直到null的時候出棧並訪問。 
  64.      */  
  65.     public static void inOrderStack(Node root){  
  66.         if(root==null)return;  
  67.         Stack<Node> s=new Stack<Node>();  
  68.         while(root!=null||!s.isEmpty()){  
  69.             while(root!=null){  
  70.                 s.push(root);//先訪問再入棧  
  71.                 root=root.left;  
  72.             }  
  73.             root=s.pop();  
  74.             System.out.println(root.value);  
  75.             root=root.right;//如果是null,出棧並處理右子樹  
  76.         }  
  77.     }  
  78.     /** 
  79.      *  
  80.      * @param root 樹根節點 
  81.      * 後序遍歷不同於先序和中序,它是要先處理完左右子樹,然後再處理根(回溯),所以需要一個記錄哪些節點已經被訪問的結構(可以在樹結構裏面加一個標記),這裏可以用map實現 
  82.      */  
  83.     public static void postOrderStack(Node root){  
  84.         if(root==null)return;  
  85.         Stack<Node> s=new Stack<Node>();  
  86.         Map<Node,Boolean> map=new HashMap<Node,Boolean>();   
  87.         s.push(root);  
  88.         while(!s.isEmpty()){  
  89.             Node temp=s.peek();  
  90.             if(temp.left!=null&&!map.containsKey(temp.left)){  
  91.                 temp=temp.left;  
  92.                 while(temp!=null){  
  93.                     if(map.containsKey(temp))break;  
  94.                     else s.push(temp);  
  95.                     temp=temp.left;  
  96.                 }  
  97.                 continue;  
  98.             }  
  99.             if(temp.right!=null&&!map.containsKey(temp.right)){  
  100.                 s.push(temp.right);  
  101.                 continue;  
  102.             }  
  103.             Node t=s.pop();  
  104.             map.put(t,true);  
  105.             System.out.println(t.value);  
  106.         }  
  107.     }  
  108.     /** 
  109.      *  
  110.      * @param root 樹根節點 
  111.      * 層序遍歷二叉樹,用隊列實現,先將根節點入隊列,只要隊列不爲空,然後出隊列,並訪問,接着講訪問節點的左右子樹依次入隊列 
  112.      */  
  113.     public static void levelTravel(Node root){  
  114.         if(root==null)return;  
  115.         Queue<Node> q=new LinkedList<Node>();  
  116.         q.add(root);  
  117.         while(!q.isEmpty()){  
  118.             Node temp =  q.poll();  
  119.             System.out.println(temp.value);  
  120.             if(temp.left!=null)q.add(temp.left);  
  121.             if(temp.right!=null)q.add(temp.right);  
  122.         }  
  123.     }  
  124. }  






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