1. 程式人生 > >二叉樹的三種遍歷非遞歸實現

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

statistic 結束 定義 style 思路 system 兩個 tor tool

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;  
    }  
}

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

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