二叉樹遍歷非遞迴寫法

2022-08-22 21:48:11 字數 2674 閱讀 1600

資料結構考試前閒的蛋疼,整理課本。

結點建立

struct

node

;node * root;

中序遍歷

模擬深搜過程,在第一次回溯的時候輸出,即為中序遍歷

1 stackq1;

2 node * pre =root;

3while (1)4

10//一直往左走

11do

12while(pre->right==null&&!q1.empty());

16//

回溯到能往左走

17if (pre->right==null) break;18

//結束的條件是 回溯到 隊列為空了,還沒找到能往左走的結點

19//

ps:結束上述迴圈的兩種情況,①隊列為空 ②回溯到能走的結點

20 pre = pre->right;21}

22 cout << endl;

中序遍歷非遞迴

先序遍歷

模擬深搜過程,在第一次加入棧的時候輸出

1

//與中序遍歷相當類似

2 stackq3;

3 pre =root;

4while (1)5

11do

12while(pre->right==null&&!q3.empty());

16if (pre->right==null) break

;17 pre = pre->right;18}

19 cout <

2021 先序遍歷非遞迴

先序遍歷非遞迴

後序遍歷

和以上兩個遍歷的區別是

中序遍歷和先序遍歷,節點輸出位置容易判斷

先序是:在加入新節點之前

中序是:在加入右兒子之前或沒有右兒子時

而對於後序遍歷

沒有右兒子或右兒子已經被遍歷完成

中序遍歷在第一次回溯之後,完全可以將根節點pop,這樣就會避免重複訪問,並且也已經輸出了。但是對於後序遍歷,是在第二遍回溯之後輸出,所以不能pop。正因如此,回溯過程無法判斷當前節點是第幾次回溯,所以需要乙個標誌變數flag。

1 stackq2;

2 pre =root;

3while (1)4

10//

一直往左走

11while(!q2.empty()&&(pre = q2.top())&&(pre->right==null||pre->flag == 1

))12

16//

回溯到能往右走,不能往右走的原因有,沒有右兒子,右結點已經被訪問

17//

do-while 和 while 的區分!

18if (q2.empty()) break;19

//搜尋結束條件

20 pre->flag = 1

;21 pre = pre->right;22}

23 cout << endl;

後序遍歷非遞迴

剛寫完部落格,想了一會,發現可以不用flag,但是需要再開乙個棧來維護。

中心思想就是,後序遍歷的第二次(從右結點)回溯輸出和沒有右兒子,都可以總結為:不能再走了就輸出!

那麼將深搜順序(按先序遍歷壓棧)一直壓入另乙個棧中,當乙個節點無路可走了那麼輸出。

那麼問題來了,怎麼根據乙個新棧來判斷他是否無路可走了呢?

直接貼**:

1 stack q1;

2 stackq3;

3 pre =root;

4 node *outp ;

5 node *before_out;

6int cnt = 0;7

while (1)8

16do

17while(pre->right==null&&!q1.empty());

21//

對乙個節點進行dfs到最深,並回溯。直到遇見有右兒子的節點

22//

可以證明對於pre來說,她的左兒子沒有乙個點有右兒子,並且左兒子全都位於q3中

23while(!q3.empty()&&(outp = q3.top())&& (outp -> right == null || outp -> right ==before_out ) )

2429

//上述迴圈,會把pre那一堆沒有右兒子的(左兒子生的後代)全部倒序(回溯順序)輸出

30if (pre->right==null) break

;31 pre = pre->right;

32//

之後q3中會存著pre pre->right;

33//

當處理完pre->right(假設已經處理完成,或假設壓根pre->right就只乙個節點),之後將會 倒序輸出這兩個點!

34//

cout << endl; 用列印標記理解更好35}

36 cout << endl;

非遞迴非flag後序遍歷

並且可以看出,外層迴圈次數是右兒子個數+1;

樹 二叉樹的前序遍歷 非遞迴寫法

今天碰到了這道題,寫一下怎麼實現樹的前序遍歷而不使用遞迴。在我之前的部落格中曾經寫過,雖然遞迴和非遞迴有著緊密的聯絡 比如思想上 但是兩者在編寫上依然有很大差別。主要體現在遞迴可以使用所謂整體法,而如果使用非遞迴的話用整體法很難想。如果使用非遞迴的話怎麼搞呢?我們只能先通過模擬,摸清大概是怎麼做的,...

樹 二叉樹的後序遍歷 非遞迴寫法

樹的前序和中序遍歷我們都已經寫完了,現在我們來寫一下樹的後序遍歷的非遞迴寫法。迴圈體內每次要執行的東西實現思路如下 先找最左邊的節點,統統入棧。利用乙個while迴圈回溯完有右子樹,或者左右節點都被訪問過了的節點,將其出棧,並將結果輸出。將指標指向右子樹。留給下一次迴圈。definition for...

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

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