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

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

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