查找二叉树某两个节点最近的共同祖先及改进方法

这个题目偶尔看到网上有个解法是这样的,如下面一个普通二叉树

《查找二叉树某两个节点最近的共同祖先及改进方法》

我们要求结点3和结点12的最近共同祖先(指针类同,改变栈的存储类型即可)。

对树进行先序遍历,我们先求从根结点到3得一条路径,放入栈中,为14-8-5-3;再求得跟结点到12得一条路径,为14-8-12,也放入栈中。

stack<int> getStack(Tree * T, int data);

stack<int> A = getStack(T, 3);

stack<int> B = getStack(T, 12);

如下图所示

《查找二叉树某两个节点最近的共同祖先及改进方法》

我们需要从栈底遍历,找到最后一个相同的元素即为要求的祖先。但是栈只能从栈顶操作,所以我们需要将两个栈反转,如下图

《查找二叉树某两个节点最近的共同祖先及改进方法》

我们将14出栈,8出栈,然后下一个元素不相同,则8既是我们所求。

改进:

上面的方法有些繁琐,下面具体说下改进的方法。

1、上述方法求栈用了两个遍历,可否用一次遍历呢?当然可以,可以设置两个全局变量,如栈A、B,当找到第一个结点(假设是3)之后A不在变化,将A赋给B,当找到第二个结点(假设是12)之后B不再变化,当两者都找到后,退出函数。

2、紧接着我们看到栈还需要反转一下,这势必会增加时间和空间复杂度。我们观察两个栈的特点,我们发现从栈底开始都是两个结点的相同祖先,那么我们如果先把左边的3出栈,此时两个栈中得元素个数便相同了,此时两个栈一次一个出栈,直到有相同的元素出栈,便得所求。

所以我们只需找出两个栈的元素个数差d,然后将元素个数多的栈先出栈d个元素。

《查找二叉树某两个节点最近的共同祖先及改进方法》

左边栈中有4个元素,右边有3个元素,d=4-3=1,左边要先出栈一个元素,先出栈元素 3。此时两个栈元素个数相同,然后同时出栈,5、12不同,出栈继续,8相同,结束。

    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/j__king/article/details/39163559
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞