前序-中序-后序-非递归-实现
1. 簡述
??? 前序,根->左子樹->右子樹,中序,左子樹->根->右子樹,后序,左子樹->右子樹->根。
??? 本文主要關注三種遍歷方式的非遞歸實現。其中,中序和后序的實現來自參考中的“二叉樹的遍歷:前序,中序,后序,層序--包括遞歸和非遞歸實現”一文及其評論,前序比較簡單,單獨寫了個實現與參考的文中實現不同。另外,對于中序和后序,實現是一樣的,也沒什么意思,加了幾行注釋,就這樣了,實現主要是核心代碼,完整代碼在參考的文章中很詳細。
2. 前序非遞歸
????首先,棧頂元素入棧,然后進入循環,每次把棧頂元素輸出,元素出棧,將該元素的右孩子(如果存在)和左孩子(如果存在)依次入棧。?
??stack<Node*>?store;
??store.push(root);?//?根結點入棧?
??while(!store.empty())?{?
????root =?store.top(); //?在循環中,root記錄的是當前準備輸出的結點
????store.pop();
????cout?<<?root->value?<<?"??";?//?輸出當前結點?
????if(root->right_child)?//?右孩子入棧?
??????store.push(root->right_child);
????if(root->left_child)?//?左孩子入棧?
??????store.push(root->left_child);?
??}
}
3. 中序非遞歸
????前序中的Root主要作為中間變量使用。這里的Root的意義是下一個要進棧的結點,初始值為根結點。
??? while (Root不為空 || 棧不為空) {
???????? if(Root不為空) // 一路向左入棧?
???????????? Root入棧
?????????????Root=Root->left_child。
??????? ?else?// 棧頂元素的左子樹都輸出過了
???????????? 輸出棧頂元素
???????????? Root=棧頂元素->right_child
???????????? 棧頂元素出棧。
??? }??
void?InOrder(Node*?root)?{??assert(NULL?!=?root);
??stack<Node*>?store;
??while(root?&&?!store.empty())?{
????if(root?!=?NULL)?{?//?只要不為空,就一路向左結點方向走去?
??????store.push(root);
??????root?=?root->left_child;
????}
????else?{?//?store.top()的左邊都走過了?
??????cout?<<?store.top()->value?<<?"??";?//?輸出當前結點?
??????root?=?store.top()->right_child;
??????store.pop();
????}
??}
}
4. 后序非遞歸
??? Root表示下一個要處理的結點,初始化為根結點,Per表示上一次剛剛輸出過的結點。
,Per的作用是對有孩子的結點進行判斷,由于算法特性,每次到某個結點時,其左子樹都輸出過了,此時只要判斷Pre是否是當前結點的右孩子,如果不是,那么說明其右子樹沒走過,那么Root=當前結點的右子樹,否則就是剛剛輸出了當前結點的右孩子,由于是后序,其右子樹也必定都輸出過了,此時只要輸出當前結點,更新Pre就好了。
??? while(Root不為空?|| 棧不為空) {
???????? if(Root不為空)?// 一路向左
????????????Root入棧
??????????? Root=Root->left_child
???????? else {?//?此時棧頂元素的左子樹都輸出過了
???????????? Root =?棧頂元素
???????????? if(Root有右孩子 && Pre不等于Root的右孩子) // 此時棧頂元素的右子樹還沒輸出
???????????????? Root=Root->right
???????????? else //?此時棧頂元素的左右子樹都輸出過了
?????????????????輸出棧頂元素
?????????????????Pre = 棧頂元素
???????????????? 棧頂元素出棧?????????????????
??????????}
??? }
void?PostOrder(Node*?root)?{??assert(NULL?!=?root);
??Node*?Pre?=?NULL;
??stack<Node*>?store;
??while(root?&&?!store.empty())?{
????if(root?!=?NULL)?{?//?一路向左?
??????store.push(root);
??????root?=?root->left_child;
????}
????else?{?//?stack.top()的左子樹都輸出完了?
??????if(store.top()->right_child!=NULL?&&?store.top()->right_child!=Pre)?{?
??????//?右子樹存在且沒有輸出過?
????????root?=?root->right_child;?
??????}?
??????else?{?//?左右子樹都輸出過了?
????????cout?<<?store.top()->value?<<?"??";
????????Pre?=?store.top();
????????store.pop();?
??????}?
????}
??}
}?
?
5. 參考
??? 二叉樹的遍歷:前序,中序,后序,層序--包括遞歸和非遞歸實現
??? http://www.cppblog.com/ngaut/archive/2006/01/01/2351.aspx
總結
以上是生活随笔為你收集整理的前序-中序-后序-非递归-实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 给你的主机防火墙添加l7-filter
- 下一篇: TextSwitcher--文本切换器