- 二叉樹的後續遍歷,是先遍歷左子樹,在遍歷右子數,最後遍歷根節點。
- 後續遍歷的過程中我們需要藉助棧來輔助
#include<iostream>
#include<stack>
//先構建一個二叉樹結構體
struct BTreeNode{
int data;
BTreeNode* lchild;
BTreeNode* rchild;
}
void postOrder(const BTreeNode* T) //const修飾T,表明在函數執行的過程中不會對T進行修改
{
stack<BTreeNode*> assistStack; //創建一個輔助站棧
BTreeNode* p = T; //變量p用來變量整個二叉樹
BTreeNode* visitorFlag; //設置一個訪問標誌,右子樹訪問過時給設置上標記。
while(!assistStack.empty() || p) //判斷條件
{
if(p) //當p不爲空時,需要一直遍歷到最左邊的一個節點。
{
assistStack.push(p); //自頂向下遍歷,最先輸出的應是最底下的節點,所以這裏是一個壓棧操作
p = p->lchild; //p遍歷時不停地取左子樹
} //注:當p沒有左子樹時,就是取對應兄弟節點的時候,所以while判斷條件需要根據棧中的節點是否爲空
else
{
p = assistStack.top(); //左子樹被遍歷完之後,棧頂上就是最近的一個左子樹,
//如果該節點爲葉子節點,那麼就走下面的else直接輸出,如果有右子樹,那麼需要用p繼續遍歷
if(p->rchild && p->rchild != visitorFlag) //p節點如果有右子樹,
//(當右子樹和標記節點一樣的話,說明右子樹已經被輸出過了,無需在操作,直接輸出該p即可)
{
p = p->rchild;
assistStack.push(p); //未被訪問過的右子樹入輔助棧,
p = p->lchild; //p繼續遍歷(繼續判斷該節點有沒有左子樹)
}
else //沒有子節點的棧頂元素則就是後續遍歷此時需要輸出的點。
{
p = assistStack.top(); //取到該棧頂元素
assistStack.pop(); //彈出該棧頂元素
visitorFlag = p; //將輸出的元素賦給標記點
std::cout<<p->data;
p = NULL; //需要將p置空,while需要繼續循環。
}
} //總之,輔助棧頂時刻保存下一個後序遍歷需要輸出的節點。
}
}