一種易理解的二叉樹後序遍歷非遞迴寫法

2021-08-04 03:06:06 字數 1229 閱讀 1840

網上流傳了很多二叉樹的非遞迴寫法,對於前序和中序,比較容易理解,對於後序,很多講的不是非常明白。參考了很多資料,本人自己寫了

首先定義基本的二叉樹

struct treenode;

typedef struct treenode * bintree;

typedef struct treenode _treenode;

1、前序和中序。

非遞迴思路如下,

a. 遇到乙個節點,訪問它,然後把它壓棧,並去遍歷它的左子樹;

b. 當左子樹遍歷結束後,從棧頂彈出該節點並將其指向右兒子,繼續a步驟;

c. 當所有節點訪問完即最後訪問的樹節點為空且棧空時,停止。

void preorder(bintree t)

if(!s.empty())

}}

2、後序

其實,二叉樹遍歷的非遞迴寫法,本質上仍然是根據遞迴寫法推導出來的。按照左右根的順序,我們自己模擬一下遞迴的過程,不難得出下面的過程。演算法思路,(1)p=p->left,一直呼叫左子樹,直到最底下一層呼叫左子樹為空。此時,令p=stack.top(),即迴圈中最後乙個不為空的左子樹。根據p->right的情況,分為下面兩種跳**(2)p->right不為空,令p=p->right,跳到(1)。看到這裡,是不是跟傳統的前序和後序非遞迴思路很像?(3)p->right為空。由於(2)(3)是(1)的兩種情況的不同跳轉,到了這裡就說明p的左右子樹均為空。因此,訪問p。接下來,我們需要乙個prev前驅。令prev=p,然後將p出棧,重新將p只向棧頂。若p的右兒子是prev,則說明,右兒子訪問完了,訪問p。這裡我們需要乙個迴圈,乙隻判斷是否需要訪問。若p的左兒子是prev,則我們需要專向它的右兒子,重新從(1)開始下一輪迴圈。下面貼出**

void postorder2(bintree t)

if(!s.empty())

//若p右兒子為空,或者右兒子前面已經訪問了,繼續訪問p

while(p->right == null || p->right == prev)

//若p的左兒子前面已經訪問了,轉向右兒子。重新開始下一輪處理。類似前序的的非遞迴處理。

if(p->left == prev)

p = p->right;}}

}

二叉樹非遞迴後序遍歷演算法的一種簡單思路

首先從簡單的例子開始 上圖二叉樹的後序遍歷序列是 231 顛倒一下就是 132 而其前序遍歷是 123 有什麼發現?後序遍歷的倒序和前序的區別只是2和3的交換,反映在演算法中就是先左後右和先右後左的差別.也就是說後序遍歷的倒序就是按先右後左順序的前序遍歷.所以我們只需要按先右後左順序去前序遍歷二叉樹...

二叉樹非遞迴後序遍歷

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

後序非遞迴遍歷二叉樹

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