二叉樹的後序遍歷 非遞迴實現

2021-07-30 14:59:58 字數 1049 閱讀 3758

leetcode中有這麼一道題,非遞迴來實現二叉樹的後序遍歷。

二叉樹的後序遍歷順序為,root->left, root->right, root,因此需要儲存根節點的狀態。顯然使用棧來模擬遞迴的過程,但是難點是怎麼從root->right轉換到root。

方法1:

對於節點p可以分情況討論

1. p如果是葉子節點,直接輸出

2. p如果有孩子,且孩子沒有被訪問過,則按照右孩子,左孩子的順序依次入棧

3. p如果有孩子,而且孩子都已經訪問過,則訪問p節點

如何來表示出p的孩是否都已經訪問過了呢?

最暴力的方法就是對每個節點的狀態進行儲存,這麼做顯然是可以的,但是空間複雜度太大了。

我們可以儲存最後乙個訪問的節點last,如果滿足 

(p->right==null && last ==p->left) || last=p->right,那麼顯然p的孩子都訪問過了,接下來可以訪問p

**如下

1 vector postorder(treenode *root) 2

19else

202627}

2829

30return

res;

31 }

方法2:
其實我們希望棧中儲存的從頂部依次是root->left, root->right, root,當符合上面提到的條件時,就進行出棧操作。有一種巧妙的方法可以做到,先上**

1 vector postorder(treenode *root) 2

18else

19 res.push_back(p->val);20}

2122

return

res;

23 }

對於每個節點,都壓入兩遍,在迴圈體中,每次彈出乙個節點賦給p,如果p仍然等於棧的頭結點,說明p的孩子們還沒有被操作過,應該把它的孩子們加入棧中,否則,訪問p。也就是說,第一次彈出,將p的孩子壓入棧中,第二次彈出,訪問p。

二叉樹非遞迴後序遍歷

注釋 後序非遞迴遍歷的難處就在,最右結點無法直接找到後繼結點,後序線索化二叉樹在這裡就不能使用遞迴了,其實知道了遞迴的運作過程就不難理解為何不能用遞迴後序線索化了遞迴詳細執行過程a b c d e f h 當遍歷到最左邊的時候,d沒有左右結點了,輸出d,需要返回b去遍歷b的右子樹,e沒有左右結點e輸...

後序非遞迴遍歷二叉樹

後序遍歷的非遞迴演算法中節點的進棧次數是兩個,即每個節點都要進棧兩次,第二次退棧的時候才訪問節點。第一次進棧時,在遍歷左子樹的過程中將 根 節點進棧,待左子樹訪問完後,回溯的節點退棧,即退出這個 根 節點,但不能立即訪問,只能借助於這個 根 去找該 根 的右子樹,並遍歷這棵右子樹,直到該右子樹全部遍...

二叉樹後序遍歷 非遞迴

二叉樹後序遍歷 非遞迴 這裡我們約定 空的節點用空格表示,按照前序遍歷來建立樹!main.cpp 2 include iostream 3using namespace std 4typedef struct node binode,bitree 9typedef struct node1stack...