您的位置:首页 > 其它

求二叉树中两个节点的最近公共祖先

2017-07-28 14:13 501 查看
要考虑以下三种种情况:

1:二叉树每个节点有parent

2:二叉树是搜索二叉树。

3:就是普通二叉树。

1:二叉树每个节点有parent

首先给出Node1的父节点Node1->_parent,然后将Node1的所有父节点依次和Node2->parent作比较,如果发现两个节点相等,则该节点就是最近公共祖先,直接将其返回。 如果没找到相等节点,则将Node2的所有父节点依次和Node1->pParent->pParent作比较……直到Node1->pParent==NULL。

struct BinaryTreeNode
{
BinaryTreeNode(int& data)
:_data(data)
,pLeft(NULL)
, pRight(NULL)
, pParent(NULL)
{}
int _data;
BinaryTreeNode* pLeft;
BinaryTreeNode* pRight;
BinaryTreeNode* pParent;
};
BinaryTreeNode* FindParent(BinaryTreeNode*Node1, BinaryTreeNode* Node2)
{
if (Node1==NULL||Node2==NULL)
return NULL;
while (Node1)
{
Node1 = Node1->pParent;
while (Node2)
{
if (Node1 == Node2->pParent)
return Node1;
Node2 = Node2->pParent;
}
}
}


2:二叉树是搜索二叉树

公共祖先值的大小位于两个节点值大小之间

typedef struct SerchBinaryTreeNode
{
SerchBinaryTreeNode(int& data)
:_data(data)
, _pLeftChild(NULL)
, _pRighChild(NULL)
{}
int _data;
SerchBinaryTreeNode* _pLeftChild;
SerchBinaryTreeNode* _pRighChild;

}SNode;
SNode* FindParent(SNode* pRoot, SNode* Node1, SNode* Node2)
{
if (pRoot == NULL||Node1 == NULL||Node2==NULL)
return NULL;
SNode* pNode = pRoot;
while (pNode)
{
if ((pNode->_data >= Node1->_data&&pNode->_data < Node2->_data)|| pNode->_data >= Node2->_data&&pNode->_data < Node1->_data)
return pNode;
else if (pNode->_data>Node1->_data)
//若pNode的节点值大于两个节点的值,则,两个节点的公共祖先节点肯定在PNode左子树,否则,反之
pNode = pNode->_pLeftChild;
else
pNode = pNode->_pRighChild;
}
}


3:就是普通二叉树。

如果两个节点分别在分界点的左右子树中,则最近的公共祖先节点为根节点

如果两个节点都在左子树中,则递归处理左子树,反之,处理右子树

struct BinaryTreeNode
{
BinaryTreeNode(int& data)
:_data(data)
, _pLeftChild(NULL)
, _pRighChild(NULL)
{}
int _data;
BinaryTreeNode* _pLeftChild;
BinaryTreeNode* _pRighChild;

};
//判断节点是否在树中
bool isInTree(BinaryTreeNode* pRoot, BinaryTreeNode* Node)
{
if (pRoot == NULL || Node == NULL)
return false;
//该节点为根节点
if (pRoot == Node)
return true;
bool flag = isInTree(pRoot->_pLeftChild,Node);//节点是否在左子树中
//r若不在,则在右子树中
if (!flag)
return isInTree(pRoot->_pRighChild,Node);
return flag;
}

BinaryTreeNode* FindParent(BinaryTreeNode*pRoot, BinaryTreeNode*Node1, BinaryTreeNode*Node2)
{
//判断Node1是否在左子树中
if (isInTree(pRoot->_pLeftChild, Node1))
{
//判断Node2是否在右子树
if (isInTree(pRoot->_pRighChild, Node2))
return pRoot;
else//两节点都在左子树中
return FindParent(pRoot->_pLeftChild,Node1,Node2);
}
else//此时Node1在右子树中
{
//判断Node2是否在左子树中
if (isInTree(pRoot->_pLeftChild, Node2))
return pRoot;
else//两个节点都在左右子树中
return FindParent(pRoot->_pRighChild,Node1,Node2);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息