二叉树:后序遍历非递归算法

分析:后序遍历是三种遍历中最难的一种,后序遍历的特点为左右根,并且也需要借助一个栈来完成,如图,虚线表示p,q最开始的位置,用r指向最近访问过的结点。首先从根节点开始,沿着根的左孩子,将左孩子依次进行入栈。当D入栈之后,由于D没有右孩子,所以将D出栈,此时r指向D。
在这里插入图片描述
D出栈之后读栈顶元素B,p指向B,发现B有右孩子,然后将右孩子E入栈。在这里插入图片描述
然后判断栈顶元素E,E没有右孩子了,所以将E出栈,此时r指向E。
在这里插入图片描述
然后判断栈顶元素B,B的两个孩子都已经操作过了,所以B出栈,p指向A,判断栈顶元素A,A有右孩子,右孩子C入栈,此时r指向C。
在这里插入图片描述
判断栈顶元素C,C无右孩子,所以C出栈,此时栈中只剩A,A的两个孩子都已经操作过了,所以A也出栈,结束,最终后序遍历结果为:DBECA
在这里插入图片描述
算法思想
1、沿着根的左孩子,依次入栈,直到左孩子为空;
2、读栈顶元素进行判定,若右孩子不空且未被访问,将右孩子执行第一步;
3、栈顶元素出栈。
代码

void PostOrder(BiTree){  // 全篇❤
	InitStack(s);
	BiTree *p=T,*r=NULL; // r标记最近访问过的结点
	while(p!=NULL || !IsEmpty(s)){
		if(p!=NULL){
			push(s,p);  // 一直向左走,左孩子入栈
			p=p->lchild;
		}
		else{
			GetTop(s,p);
			// 获取s的栈顶元素赋值给p
			// GetTop(s,p)意思就是判断栈顶元素的情况
			//❤case one❤
			if(p->rchild && p->rchild!=r){
			// 若右孩子存在且未被访问
				p=p->rchild;  // 就让右孩子
				push(s,p)  // 入栈
				p=p->lchild;  // 让右孩子向左
				//上面三句意思就是让右孩子的左孩子一直入栈,一直向左走
			}
			// ❤case two❤
			else{
				pop(s,p);  // 右孩子为空或未被访问过,就出栈
				visit(p->data);
				r=p;  // r标记最近访问结点
				p=NULL;  // r置空
				// 置空原因:因为这个结点已经出栈了
				//继续指向就没必要了,置空后r不标记任何结点
			}
		}
	}
}
  • 85
    点赞
  • 362
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花间半盘棋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值