树的遍历——后序遍历的非递归算法

算法思路

        后序遍历的非递归算法。思路参考来自这里。思路是当当前结点没有左孩子或右孩子或左孩子和右孩子已经被访问的情况下,访问该结点。 具体思路如下:

  1. 当前结点左子树不为空且左孩子和右孩子没有被访问过的情况下,不断入栈左子树;
  2. 左子树访问结束,判断当前结点是否有右孩子且右孩子没有访问过的情况下,入栈右孩子,回到步骤1;
  3. 当最后一个右孩子被访问到时,开始出栈,并记录上一次 范围的结点。

算法实现

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];
			}
		}
	}
}

 

  • 19
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值