寻找树中两个结点的最低公共祖先

在二叉树中寻找两个结点的最低公共祖先,可以通过多种方式实现。对于BST树,可以利用节点值的关系判断;如果有指向父节点的指针,可以从两个结点遍历到根节点找到交点;如果没有父节点指针,可以使用前序遍历记录必经路径并找到相交点。
摘要由CSDN通过智能技术生成

寻找树中两个结点的最低公共祖先

Q:在树中寻找两个结点的最低公共祖先,是什么意思呢?

A:树是由根节点衍生左右孩子继续衍生左右孩子的左右孩子。所以呢树中的两个结点是一定拥有最低公共祖先(这两个结点Q:是在这个祖先结点衍生的孩子中)至于最低:就是第一个公共祖先。


  • 树是二叉树并且是BST树嘛?
    我们根据BST树(二叉搜索树/二叉排序树)的特性:树中任意结点的val大于左孩子的val。

    如果该结点是这两个结点的最低公共祖先
    那么他的val一定是大于等于其中一个结点的val,并且小于另外一个结点的val

    或者小于等于其中一个结点的val并且大于另外一个结点的val。
    在这里插入图片描述
    如上图三种情况,此图省略了父节点和孩子之间的结点,不代表不存在

typedef int KeyType;
typedef struct BstNode{
	BstNode*left;
	BstNode*right;
	BstNode*parent;
	KeyType key;
}BstNode;
typedef struct BstTree{
	BstNode* head;
	KeyType cursize;   //BST树中结点个数(不包括头结点)
}BstTree;
BstNode* lowestCommonAncestor(BstNode*root, BstNode*p, BstNode*q)
{
	while (1)
	{
		if (root->key > max(p->key, q->key))
		{
			root = root->left;
		}
		else if (root->key < min(p->key, q->key))
		{
			root = root->right;
		}
		else 
		{
		    //如上图三种形式
			return root;
		}
	}
}

  • 如果是一颗普通的树,并且拥有指向父结点的指针
    如果拥有指向父结点的指针,我们就可以从两个结点开始往根遍历。显示成两条链表,两个链表相交的结点就是最低公共祖先结点。
    在这里插入图片描述

如图所示,寻找F和H的最低公共祖先,利用parent指针往根遍历,我们可以的得到两个链表:
FDBA 和HEBA
两个链表相交于B结点,所以公共祖先是结点B。


  • 没有指向父结点的指针的树
    这里我们用的树的前序遍历,前序遍历的规则:父节点,左孩子,右孩子。 这里的前序遍历为我们提供了很大帮助,但是不是完全利用前序遍历。

在这里插入图片描述
如上图树所示。我们需要申请两个辅助空间,来存放到达这两个结点的必经路径。我们根据前序遍历的规则如下演示:

寻找F的必经路径:
①A
②A->B
③A->B->D
④A->B->D->F
所以ABD到F的必经路径

寻找H的必经路径:
①A
②A->B
③A->B->D
④A->B->D->F
F的左右孩子都为空,所以无法到达H,删除F。
⑤A->B->D->G
G的左右孩子都为空,所以无法到达H,删除G。
因为D的两个孩子都无法到达H,所以删除D。
⑥A->B->E
⑦A->B->E->H
所以ABE到H的必经路径

两链表相交于B,所以B结点时F,H两结点的最低公共祖先。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值