二叉樹的三種遍歷非遞歸實現


 

1.二叉樹前序遍歷的非遞歸實現

     * 實現思路,先序遍歷是要先訪問根節點,然后再去訪問左子樹以及右子樹,這明顯是遞歸定義,但這里是用棧來實現的
     * 首先需要先從棧頂取出節點,然后訪問該節點,如果該節點不為空,則訪問該節點,同時把該節點的右子樹先入棧,然后

     * 左子樹入棧。循環結束的條件是棧中不在有節點。即 !s.empty() 

 
public void preOrder(Node root) {  
    Stack<Node> s = new Stack<Node>();  
    s.push(root);  
    Node p = null;  
    while (!s.empty()) {  
        p = s.pop();  
        if (p != null) {  
            System.out.print(p.val+" ");  
            s.push(p.right);  
            s.push(p.left);  
        }  
    }  
}  

 

2.二叉樹的中序遍歷非遞歸實現

     * 實現思路,中序遍歷是要先遍歷左子樹,然后跟節點,最后遍歷右子樹。所以需要先把跟節點入棧然后在一直把左子樹入棧
     * 直到左子樹為空,此時停止入棧。棧頂節點就是我們需要訪問的節點,取棧頂節點p並訪問。然后改節點可能有右子樹,所以
     * 訪問完節點p后還要判斷p的右子樹是否為空,如果為空則接下來要訪問的節點在棧頂,所以將p賦值為null。如果不為空則
     * 將p賦值為其右子樹的值。 循環結束的條件是p不為空或者棧不為空。

 

public void inOrder(Node root) {  
      Stack<Node> s = new Stack<Node>();  
      Node p = root;  
      do {  
          while (p != null) {  
             s.push(p);  
             p = p.left;  
          }  
          p = s.pop();  
          System.out.print(p.val+" ");  
          if (p.right != null) {  
              p = p.right;  
          }  
          else p = null;  
     } while(p != null || !s.empty());  
}  

 

3.二叉樹的后序遍歷里非遞歸實現

     * 實現思路,在進行后序遍歷的時候是先要遍歷左子樹,然后在遍歷右子樹,最后才遍歷根節點。所以在非遞歸的實現中要先把根節點入棧
     * 然后再把左子樹入棧直到左子樹為空,此時停止入棧。此時棧頂就是需要訪問的元素,所以直接取出訪問p。在訪問結束后,還要判斷被訪
     * 問的節點p是否為棧頂節點的左子樹,如果是的話那么還需要訪問棧頂節點的右子樹,所以將棧頂節點的右子樹取出賦值給p。如果不是的
     * 話則說明棧頂節點的右子樹已經訪問完了,那么現在可以訪問棧頂節點了,所以此時將p賦值為null。判斷結束的條件是p不為空或者棧
     * 不為空,若果兩個條件都不滿足的話,說明所有節點都已經訪問完成。 

  public void postOrder(Node root) {  
      
    Stack<Node> s = new Stack<Node>();  
    Node p = root;  
    while (p != null || !s.empty()) {  
        while(p != null) {  
            s.push(p);  
            p = p.left;  
        }  
        p = s.pop();  
        System.out.print(p.val+" ");  
        //這里需要判斷一下,當前p是否為棧頂的左子樹,如果是的話那么還需要先訪問右子樹才能訪問根節點  
        //如果已經是不是左子樹的話,那么說明左右子書都已經訪問完畢,可以訪問根節點了,所以講p復制為NULL  
        //取根節點  
        if (!s.empty() && p == s.peek().left) {  
            p = s.peek().right;  
        }  
        else p = null;  
    }  
}  

 

最后附上節點的Java類代碼

 

//樹的節點類  
class Node {  
    public int val; //節點值  
    public Node left; //左子樹  
    public Node right; //右子樹  
    public Node() {}  
    public Node(int val, Node left, Node right) {  
        this.val = val;  
        this.left = left;  
        this.right = right;  
    }  
}

參考:二叉樹的三種遍歷非遞歸實現

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM