【数据结构】在二叉树中有两个结点m和n,若m是n的祖先,则使用后序遍历可以找到从m到n的路径

题干分析:

首先要注意题目中说到的路径,不是在visit()时得到的序列,而是看某时刻栈中的序列。这里的路径是这样理解的,访问一个结点 x 时,栈中结点恰好是 x 结点的所有祖先,从栈底到栈顶结点再加上 x 结点,这样就构成了从根结点到 x 结点的一条路径。
在王道数据结构P134中有讲到这句话。

比如先序遍历的非递归算法,在n进栈之前,m就已经出栈了。中序也是同样的。

  • 下面以先序为例,对照代码,演示一下栈中元素的出入栈过程。
    以此二叉树为例
void PreOrder(BiTree T){
	InitStack(S);
	BiTree p = T;
	while(p||!IsEmpty(S)){
		if(p){
			visit(p);Push(S,p);
			p=p->lchild;
		}else{
			Pop(S,p); //注意Pop操作!
			p=p->rchild;
		}
	}
}

1、p指向m结点,进入循环,p非空,将m入栈,p=p->lchild,p又指向了a结点。见图1。
2、满足条件,再进入循环,p非空,a入栈,p=p->lchild,此时p为null。见图2。
3、此时栈不为空,进入循环,p为null,栈顶元素a出栈时,p指向a结点,p=p->rchild 后,p还是为null。见图3。
4、此时栈还是不为空,进入循环,p为null,栈顶元素m出栈时,p指向m结点(注意在Pop(S,p)操作中,栈顶元素出栈时,p 是指向出栈的那个元素的,有一个赋值的步骤),p=p->rchild,p现在指向了b结点。见图4。(图中p是m出栈时的指向,p’是p->rchild赋值后的指向)此刻栈中元素为空。在n进栈之前,m就已经出栈了。栈中已经没有从m到n的路径了。所以先序遍历不适合。
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述

总结

中序遍历的非递归算法和先序相比只是 visit() 的位置不同,visit() 的位置不影响栈中的路径,所以先序、中序都不适合。只有后序遍历的非递归算法可以,当利用后序遍历到目标结点 n 时,栈中的序列就为 n 结点的全部祖先结点。(路径顺序是从栈底到栈顶!)
小伙伴们可以用文中此例自行验证后序非递归的过程。

  • 30
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值