您的位置:首页 > Web前端

剑指offer-树中两个节点的最低公共祖先

2017-07-28 21:29 435 查看
对于这个问题不同的条件可以有不同的解法

树是二叉树且是二叉搜索树。



BinaryTreeNode *GetLastCommonParent(BinaryTreeNode *pRoot,BinaryTreeNode *pNode1,BinaryTreeNode *pNode2)
{
if (NULL == pRoot)
return NULL;
if (pRoot->_data > pNode1->_data && pRoot->_data > pNode2->_data) //当前结点的值比两个节点的值都大公共祖先一定在左子树中
return GetLastCommonParent(pRoot->_pLeft, pNode1, pNode2);
else if (pRoot->_data < pNode1->_data && pRoot->_data < pNode2->_data)//前结点的值比两个节点的值都小公共祖先一定在右子树中
return GetLastCommonParent(pRoot->_pRight, pNode1, pNode2);
else //
return pRoot;
}


树中的每个结点都有指向父结点的指针



这样就转换成了求两个链表的第一个公共结点。

普通二叉树(没有父结点指针)





实现代码

//普通二叉树,没有parent指针
//非递归的解法
//1.获取结点所在的路径,将路径保存在链表里
bool GetNodePath(BinaryTreeNode *pRoot, BinaryTreeNode *pNode, list<BinaryTreeNode*>&path)
{
if (NULL == pRoot || NULL == pNode)
return false;
if (pRoot == pNode)
return true;
path.push_back(pRoot);
bool found = false;
found = GetNodePath(pRoot->_pLeft, pNode, path);
if (!found)
found = GetNodePath(pRoot->_pRight, pNode, path);
if (!found)
path.pop_back();
return found;
}
//2. 寻找两个链表的公共节点
BinaryTreeNode *GetCommNode(const list<BinaryTreeNode *>&path1,const list<BinaryTreeNode *> &path2)
{
list<BinaryTreeNode *>::const_iterator iter1 = path1.begin();
list<BinaryTreeNode *>::const_iterator iter2 = path2.begin();
BinaryTreeNode *pNode = NULL;
while (iter1 != path1.end() && iter2 != path2.end())
{
if (*iter1 == *iter2)
pNode = *iter1;
iter1++;
iter2++;
}
return pNode;
}
BinaryTreeNode *GetCommParent(BinaryTreeNode *pRoot, BinaryTreeNode * pNode1, BinaryTreeNode *pNode2)
{
if (NULL == pRoot || NULL == pNode1 || NULL == pNode2)
return NULL;
list<BinaryTreeNode *> path1;
list<BinaryTreeNode *> path2;
BinaryTreeNode *Parent = NULL;
bool ret1 = GetNodePath(pRoot, pNode1, path1);
bool ret2 = GetNodePath(pRoot, pNode2, path2);
if (ret1 && ret2)
{
Parent = GetCommNode(path1, path2);
}
return Parent;
}




非递归解法:



//递归解法
bool FindNode(BinaryTreeNode *pRoot, BinaryTreeNode *pNode)
{
if (NULL == pRoot)//上层调用函数已经进行了判空
return false;
if (pRoot == pNode)
return true;
bool found = false;
found = FindNode(pRoot->_pLeft, pNode);
if (!found)
found = FindNode(pRoot->_pRight, pNode);
return found;
}
BinaryTreeNode *GetCommonParent1(BinaryTreeNode *pRoot,BinaryTreeNode *pNode1,BinaryTreeNode *pNode2)
{
if (NULL == pRoot || NULL == pNode1 || NULL == pNode2)
return NULL;
if (FindNode(pRoot, pNode1) && FindNode(pRoot, pNode2))
{
if (FindNode(pRoot->_pLeft, pNode1) && FindNode(pRoot->_pLeft, pNode2))
return GetCommonParent1(pRoot->_pLeft, pNode1, pNode2);
else if (FindNode(pRoot->_pRight, pNode1) && FindNode(pRoot->_pRight, pNode2))
return GetCommonParent1(pRoot->_pRight, pNode1, pNode2);
else
return pRoot;
}
return NULL;
}


思路参考自剑指offer,解析摘自剑指offer.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: