- 二叉树的后续遍历,是先遍历左子树,在遍历右子数,最后遍历根节点。
- 后续遍历的过程中我们需要借助栈来辅助
#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需要继续循环。
}
} //总之,辅助栈顶时刻保存下一个后序遍历需要输出的节点。
}
}