算法思路
后序遍历的非递归算法。思路参考来自这里。思路是当当前结点没有左孩子或右孩子或左孩子和右孩子已经被访问的情况下,访问该结点。 具体思路如下:
- 当前结点左子树不为空且左孩子和右孩子没有被访问过的情况下,不断入栈左子树;
- 左子树访问结束,判断当前结点是否有右孩子且右孩子没有访问过的情况下,入栈右孩子,回到步骤1;
- 当最后一个右孩子被访问到时,开始出栈,并记录上一次 范围的结点。
算法实现
void PostOrder(BiTree T){ //入栈所有的左子树以及左子树的右子树直到没有可以访问的右子树后退栈。
BiTNode *pre = T; //记录上一次退栈的结点
BiTNode *p=T; //当前访问结点
BiStack s ; //保存结点用的栈
s.top=0; //栈底预留,用于保存NULL结束算法。
s.data[s.top]=NULL;
while(p||s.top!=0){
if(p!=NULL&&pre!=p->lchild&&pre!=p->rchild){ //结点不为空且左孩子和右孩子没有访问过 ,入栈左子树
s.data[++s.top]=p;
p=p->lchild;
}
else{
p=s.data[s.top];
if(p->rchild!=NULL&&pre!=p->rchild){ //右子树不为空且右孩子没有访问过,入栈右子树结点
p=p->rchild;
}
else{
printf("%d ",p->data); //访问到最后的右子树的结点后,退栈。
pre=s.data[s.top];
p=s.data[--s.top];
}
}
}
}
C编程实现
#include<stdio.h>
typedef struct BiTNode{
int data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
typedef struct{
BiTree data[100];
int top;
}BiStack;
void PostOrder(BiTree T);
int main(){
BiTNode a,b,c,d,e,f,g; //简单的测试数据
a.data=1;
b.data=2;
c.data=3;
d.data=4;
e.data=5;
f.data=6;
g.data=7;
a.lchild=&b;
a.rchild=&g;
b.lchild=&c;
b.rchild=NULL;
c.lchild=&d;
c.rchild=&e;
d.lchild=NULL;
d.rchild=NULL;
e.lchild=NULL;
e.rchild=&f;
f.lchild=NULL;
f.rchild=NULL;
g.lchild=NULL;
g.rchild=NULL;
PostOrder(&a);
return 0;
}
void PostOrder(BiTree T){ //入栈所有的左子树以及左子树的右子树直到没有可以访问的右子树后退栈。
BiTNode *pre = T; //记录上一次退栈的结点
BiTNode *p=T; //当前访问结点
BiStack s ;
s.top=0;
s.data[s.top]=NULL;
while(p||s.top!=0){
if(p!=NULL&&pre!=p->lchild&&pre!=p->rchild){ //结点不为空且左孩子和右孩子没有访问过 ,入栈左子树
s.data[++s.top]=p;
p=p->lchild;
}
else{
p=s.data[s.top];
if(p->rchild!=NULL&&pre!=p->rchild){ //右子树不为空且右孩子没有访问过,入栈右子树结点
p=p->rchild;
}
else{
printf("%d ",p->data); //访问到最后的右子树的结点后,退栈。
pre=s.data[s.top];
p=s.data[--s.top];
}
}
}
}