日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

前序-中序-后序-非递归-实现

發布時間:2024/4/14 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 前序-中序-后序-非递归-实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 簡述

??? 前序,根->左子樹->右子樹,中序,左子樹->根->右子樹,后序,左子樹->右子樹->根。
??? 本文主要關注三種遍歷方式的非遞歸實現。其中,中序和后序的實現來自參考中的“二叉樹的遍歷:前序,中序,后序,層序--包括遞歸和非遞歸實現”一文及其評論,前序比較簡單,單獨寫了個實現與參考的文中實現不同。另外,對于中序和后序,實現是一樣的,也沒什么意思,加了幾行注釋,就這樣了,實現主要是核心代碼,完整代碼在參考的文章中很詳細。
2. 前序非遞歸
????首先,棧頂元素入棧,然后進入循環,每次把棧頂元素輸出,元素出棧,將該元素的右孩子(如果存在)和左孩子(如果存在)依次入棧。?

void?PreOrder(Node*?root)?{ ? assert(NULL != root)
??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

總結

以上是生活随笔為你收集整理的前序-中序-后序-非递归-实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。