使用两个栈,一个栈s1用于存储输出内容,另一个栈s2用于存储左节点。
大概流程是从根节点开始,不断向右前进,将遇到的节点都存储进s1,若遇到的节点有左节点则将其左节点存入s2。前进到右节点为空之后,如果s2不为空,则将存储左节点的s2出栈,继续从此出栈的元素开始,不断向右推进,即重复上一步骤,直到s2为空,退出循环。
void postOrder(TreeNode *TT){
Stack s1,s2; // 创建初始化顺序栈。
while(1)
if(TT){
s1.push(TT); //将遇到的节点都推进s1
if(TT->lchild) s2.push(TT->lchild); //将左节点推进s2
TT = TT->rchild; //向右前进
}else{
if(s2.isEmpty()) break; //退出循环
TT = s2.pop(); //回到刚刚存储的左节点
}
while(!s1.isEmpty()) printf("%d\t",s1.pop()); //s1依次出栈
}
类似的思想可以用于二叉树的先序和中序遍历算法上。相较于传统算法,这种方法对栈的操作量更少,因此占用内存更少,且运行速度更快。
先序遍历:
void preOrder(treeNode* TT){
Stack st; //创建一个栈,用于记录右节点
while(1)
if(TT){
print("%d\t", TT->data);
if(TT->rchild) st.push(TT->rchild);
TT = TT->lchild; //向左推进
}else{
if(st.isEmpty()) break;
TT = s