二叉樹非遞迴遍歷,使用狀態機的簡單寫法

2021-10-04 13:36:09 字數 1089 閱讀 9877

使用狀態機演算法簡單解決二叉樹非遞迴遍歷

今天我本來是準備複習一下資料結構的。看到二叉樹的遍歷之後,想著老師好像講過一種不用遞迴的遍歷方法,於是就想自己寫一下。寫了一小時發現不對勁,去網上找了篇部落格看看,媽耶這也太複雜了吧,硬著頭皮寫完前序遍歷和中序遍歷,乙個比乙個複雜。。。然後我靈機一動,想到用狀態機,發現效果出奇的好,簡簡單單搞定了。下面是思路和分析。

樹的定義

struct treenode 

};

先看看使用遞迴的方法

void funl(treenode* t)
簡簡單單,輕輕鬆鬆,甚至就跟定義一樣長。。

然後嘗試一下非遞迴方法,發現,在處理乙個節點的時候,其實是沒辦法知道這個節點已經被怎麼處理了。對先序遍歷而言,應該是先輸出,左節點入棧,右節點入棧。但是對取出的節點不能判斷已經對它操作到了那一步。

通常的做法是,迴圈巢狀,進行左節點入棧時讓他迴圈直到左節點為空,然後尋找可以遍歷的右節點這樣。。。每個步驟放在乙個迴圈裡,迴圈套迴圈這樣子。。對我來說有點太難了。。。放棄。

//中序遍歷 

void funm(treenode *t)

while(!s.empty())

} }cout<

回頭想一下,為什麼用遞迴就這麼簡單呢?我覺得主要在於,在這個遞迴使用時,其實不僅僅把引數傳進去了,而且當前執行到的位置也被儲存了,這樣其實就是多了一些狀態資訊(知道已經執行到那一步了),知道現在在哪一步當然就不用那麼麻煩了。

等等,狀態?那就狀態機走一波?加乙個狀態棧,儲存現在執行到的狀態。執行時可以根據該節點狀態就可以知道要執行什麼步驟了,因此只要來乙個迴圈不斷判斷即可。狀態機的狀態定義如下:

狀態1:待左遍歷,如果左節點非空,左節點入棧,轉到2狀態

狀態2:待右遍歷,如果右節點非空,右節點出棧,轉到3狀態

狀態3:待輸出,輸出該節點,出棧

初始狀態為1

void funr(treenode *t)

}}

看起來挺多,其實也就是狀態轉換,只要寫每個狀態轉換時的步驟即可。思想挺簡單的。(起碼比那篇部落格的純迭代容易理解多了。。)

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

二叉樹以及對二叉樹的三種遍歷 先根,中根,後根 的遞迴遍歷演算法實現,以及先根遍歷的非遞迴實現。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次函式呼叫,這將極大地增加程式執行時間。這時,應該採取非遞迴便利二叉...