您的位置:首页 > 其它

求两个节点的最近公共祖先节点

2017-07-28 22:14 267 查看
解法分三种情况:

1.节点有parent,即是三叉链。若是每个节点都有指向父节点的指针,则问题可以变形成求链表相交节点问题。这时就可以让路径长的节点先走几步,接着同时走,判断两个节点是否相等。

int GetLength(Node *node)
{
if (node == NULL)
return 0;
int len = 0;
while (node)
{
node = node->_parent;
len++;
}
return len;
}
//求两个节点的最近公共祖先,有指向父节点的指针的情况,转化为求两个链表的交点问题
Node *FindCommonAncestor(Node *node1, Node *node2)
{
if (_root == NULL || node1 == NULL || node2 == NULL)
return NULL;
Node* LongLen = NULL;
Node* ShortLen = NULL;
//分别求出从两个节点到跟节点的路径
int len1 = GetLength(node1);
int len2 = GetLength(node2);
int temp = abs(len1 - len2); //求出两个路径之差

if (len1 > len2)
{
LongLen= node1;
ShortLeng = node2;
}
else
{
LongLen= node2;
ShortLen = node1;
}
//让路径较长的先走
for (int i = 0; i < temp; i++)
LongLeng = LongLeng->_parent;
//接下来一起向前走,直到找到公共节点停止
while (LongLen&& ShortLen && (LongLen->_data != ShortLen->_data))
{
LongLen = LongLen->_parent;
ShortLen = ShortLen->_parent;
}
//直到找到公共节点
if (LongLen->_data == ShortLen->_data)
return LongLen;
else
return NULL;

}


2.二叉树是二叉搜索树

 可使用递归算法解决,根据搜索二叉树左子树的所有节点比根节点小,右子树的所有节点比跟节点大的性质,若两个节点都比根结点小,则递归左子树,若都比根结点大,则递归右子树,若两个节点一左一右,就可找出当前节点,此时当前节点是最近公共祖先 。

Node* _FindCommonAncestor(Node *&root,Node *&node1, Node *&node2)
{
if (_root == NULL || node1 == NULL || node2 == NULL)
return ;
//1.两个节都小于根节点,最近公共祖先在左子树中
if ((node1->_data < root->_data) && (node2->_data < root->_data))
_FindCommonAncestor(root->_left, node1, node2);
//2.两个节都大于根节点,最近公共祖先在右子树中
else if ((node1->_data> root->_data) && (node2->_data > root->_data))
_FindCommonAncestor(root->_right, n1, n2);
else //3.一个在左子树,一个在右子树,找到公共祖先root
return root;
}
3.二叉树是普通树

                                                                                                                                                                                                                                                              

      从根节点开始遍历,如果node1和node2中的任一个和root匹配,那么root就是最近公共祖先。 如果都不匹配,则分别递归左、右子树,如果有一个 节点出现在左子树,并且另一个节点出现在右子树,则root就是最近公共祖先.  如果两个节点都出现在左子树,则说明最近公共祖先在左子树中,否则在右子树。

BinaryNode* GetLastCommonAncestor(Node *root, Node *node1, Node *node2)
{
if (root == NULL || node1 == NULL || node2 == NULL)
return NULL;

if (node1 == root || node2 == root)
return root;

BinaryNode* Left_Lca = GetLastCommonAncestor(root->_left, node1, node2);
BinaryNode* Right_Lca = GetLastCommonAncestor(root->_right, node1, node2);
if (Left_Lca && Right_Lca)
return root;
if (Left_Lca == NULL)
return Right_Lca;
else
return Left_Lca;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: