题目:输入两个树结点,求它们的最低公共祖先。
http://www.gocalf.com/blog/least-common-ancestor.html
http://m.blog.csdn.net/blog/huoyaotl123/42155067 (二叉树中两个树结点的最低公共祖先)
事实上,这是一组题目,
情况一:此树为二叉树,且为二叉搜索树;
二叉搜索树是排过序的,位于左子树的结点都比父节点小;位于右子树的结点都比右子树大,我们只需要从树的根节点开始和两个输入的结点进行比较,如果当前结点的值比两个结点的值都要大,那么最低公共父节点一定在当前结点的左子树中,于是下一步遍历当前结点的左子树。如果当前结点的值比两个结点的值都小,那么最低公共父节点一定在当前结点的右子树中,于是下一步遍历当前结点的右子树结点。这样在树中从上到下找到的第一个在两个输入结点的值之间的结点,就是最低的公共祖先。
struct node *least_common_parent(bstree *root,struct node *a,struct node *b)
{
if (root==NULL || a==NULL || b==NULL)
return NULL;
while (root != NULL) {
if (root->key > a->key && root->key > b->key)
root = root->lchild;
else if (root->key < a->key && root->key < b->key)
root = root->rchild;
else
return root;
}
return NULL;
}
情况二:此树就是普通的树时;
struct TreeNode
{
int val;
vector<TreeNode*> children;
};//多叉树结构
bool GetNodePath(TreeNode* root, TreeNode* node, list<TreeNode*>& path)
{ //用来得到从根节点到node结点的路径,路径保存在path中
if (root == node)
path.push_back(node);
bool found = false;
vector<TreeNode*>::iterator it = root->children.begin();
while (!found && it != root->children.end())
{
found = GetNodePath(*it, node, path);
++it;
}
if (!found)
path.pop_back();
return found;
}
TreeNode* GetLastCommonNode(const list<TreeNode*>& path1, const list<TreeNode*>& path2)
{ //求两个路径的最后一个公共结点
list<TreeNode*>::const_iterator it1 = path1.begin();
list<TreeNode*>::const_iterator it2 = path2.begin();
TreeNode* res = NULL;
while (it1 != path1.end() && it2 != path2.end())
{
if (*it1==*it2)
res = *it1;
it1++;
it2++;
}
return res;
}
TreeNode* GetLastCommonParent(TreeNode* root, TreeNode* node1, TreeNode* node2)
{
if (root == NULL || node1 == NULL || node2 == NULL)
return NULL;
list<TreeNode*> path1;
GetNodePath(root, node1, path1);
list<TreeNode*> path2;
GetNodePath(root, node2, path2);
return GetLastCommonNode(path1, path2);
}