对于这个问题不同的条件可以有不同的解法
树是二叉树且是二叉搜索树。
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.