二叉樹的非遞迴遍歷

2021-09-13 09:54:25 字數 1633 閱讀 2250

二叉樹前序、中序、後序的非遞迴遍歷可以借助棧實現(遞迴形式轉為借助棧和迴圈實現),層序遍歷可以借助佇列實現。在構思遍歷的步驟時,可以在紙上隨意畫乙個三層的二叉樹,用棧後進先出的思想去嘗試。

1、先序遍歷遇到乙個節點,將其push入棧;

判斷棧頂是否有節點,如果有,pop出棧並cout(訪問)。檢查該節點是否有子樹,如果該節點有子樹,按照先右子樹後左子樹的順利將子節點push入棧;如果沒有左右子樹,檢查棧是否空,更新棧頂。

重複2,直到棧沒有元素。

//非遞迴實現先序遍歷

void preordertra(bintree *bt)

p = s.top;

}}

或者寫成如下:

遇到乙個節點,將其push入棧,並cout出來,按先序遍歷規則去遍歷節點的左子樹;

當左子樹遍歷結束(或左子樹為空),將棧頂節點更新為當前節點,從棧頂彈出這個節點;

然後從其右指標出發,按中序遍歷規則遍歷其右子樹;

不斷的對上面做迴圈,知道樹和棧都為空。

void inordertra(bintree *proot)

if(!s.empty())

}}

2、中序遍歷在先序遍歷的基礎上,我們稍作調整就可以得到中序遍歷的非遞迴演算法。因為中序遍歷是先遍歷左子樹,再訪問節點,後遍歷右子樹,所以得到:

遇到乙個節點,將其push入棧,按中序遍歷規則去遍歷節點的左子樹;

當左子樹遍歷結束(或左子樹為空),將棧頂節點更新為當前節點,並從棧頂彈出這個節點,並cout出來;

然後從其右指標出發,按中序遍歷規則遍歷其右子樹;

不斷的對上面做迴圈,知道樹和棧都為空。

void inordertra(bintree *proot)

if(!s.empty())

}}

3、後序遍歷後序遍歷先訪問左子樹,再訪問右子樹,後訪問根節點,對於每個子樹來說,又按照同樣的訪問順序進行遍歷。後序遍歷的非遞迴的實現相要保證根節點在左子樹和右子樹被訪問後才能訪問,我們可以定義乙個陣列,用於標記每乙個節點是否被訪問過。思路如下:

void postorder(bintree *proot)        

if(!s.empty())

p=s.top;

p=p->right;

tag[index]=1;

index--;}}

}

4、層序遍歷

借助佇列實現:當遇到乙個節點就進入佇列,當這個節點出隊時,如果存在左右孩子,將其左孩子節點先入隊,右孩子**隊,不斷迴圈直到樹和佇列都為空。

void floortra(bintree *proot) 

while (!q.empty())

if (p->right != null)

q.pop(); }}

}

二叉樹遍歷(遞迴 非遞迴)

二叉樹以及對二叉樹的三種遍歷 先根,中根,後根 的遞迴遍歷演算法實現,以及先根遍歷的非遞迴實現。node public class node public node left public node right public object value 遍歷訪問操作介面 public inte ce ...

二叉樹非遞迴遍歷

二叉樹非遞迴遍歷的幾個要點 1 不管前序 中序還是後序,它們的遍歷路線 或者說是回溯路線,先沿左邊一直走到盡頭,然後回溯到某節點,並跳轉到該節點的右孩子 如果有的話 然後又沿著這個有孩子的左邊一直走到盡頭 都是一樣的。2 明確每次回溯的目的。比如,前序回溯的目的是為了訪問右子樹 中序回溯的目的是為了...

非遞迴遍歷二叉樹

中序遞迴遍歷 void inordertrvdigui node pnode 然而,當樹的深度很大 比如16 時 假設為滿二叉樹 樹的節點數為 2 0 2 1 2 2 2 15 2 16 65536,遍歷整個二叉樹意味著有65536次函式呼叫,這將極大地增加程式執行時間。這時,應該採取非遞迴便利二叉...