資料結構考試前閒的蛋疼,整理課本。
結點建立
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;非遞迴非flag後序遍歷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;
並且可以看出,外層迴圈次數是右兒子個數+1;
樹 二叉樹的前序遍歷 非遞迴寫法
今天碰到了這道題,寫一下怎麼實現樹的前序遍歷而不使用遞迴。在我之前的部落格中曾經寫過,雖然遞迴和非遞迴有著緊密的聯絡 比如思想上 但是兩者在編寫上依然有很大差別。主要體現在遞迴可以使用所謂整體法,而如果使用非遞迴的話用整體法很難想。如果使用非遞迴的話怎麼搞呢?我們只能先通過模擬,摸清大概是怎麼做的,...
樹 二叉樹的後序遍歷 非遞迴寫法
樹的前序和中序遍歷我們都已經寫完了,現在我們來寫一下樹的後序遍歷的非遞迴寫法。迴圈體內每次要執行的東西實現思路如下 先找最左邊的節點,統統入棧。利用乙個while迴圈回溯完有右子樹,或者左右節點都被訪問過了的節點,將其出棧,並將結果輸出。將指標指向右子樹。留給下一次迴圈。definition for...
二叉樹遍歷(遞迴 非遞迴)
二叉樹以及對二叉樹的三種遍歷 先根,中根,後根 的遞迴遍歷演算法實現,以及先根遍歷的非遞迴實現。node public class node public node left public node right public object value 遍歷訪問操作介面 public inte ce ...