您的位置:首页 > 其它

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

2015-06-19 16:09 274 查看
(编程之美)求树中两个节点的最短公共祖先。

情况一:二叉搜索树

二叉搜索树都是排序过的,位于左子树的节点都比父节点小,而位于右子树上面的节点都比父节点大。

如果当前节点的值比两个结点 的值都大,那么最低的共同的父节点一定是在当前节点的左子树中,于是下一步遍历当前节点的左子节点。

如果当前节点的值比两个结点的值都小,那么最低的共同的父节点一定是在当前节点的右子树中,于是下一步遍历当前节点的右子节点。

这样从上到下,找到的第一个在两个输入结点的值之间的节点,就是最低的公共祖先。

情况二:这是一颗普通的树,但是有指向父节点的指针

题目等价于求解两个链表的第一个公共节点问题

情况三:这是一颗普通的树,没有指向父节点的指针

用两个链表分别保存从根节点到输入的两个结点的路径,然后把问题转换成两个链表的最后公共节点。

代码如下:

#include<iostream>
#include<list>
using namespace std;

struct TreeNode
{
int value;
TreeNode* left;
TreeNode* right;
TreeNode(int nvalue):value(nvalue),left(NULL),right(NULL){};
};

bool GetNodepath(TreeNode* pRoot,TreeNode* pNode,TreeNode*path[15],int flag)
{
if(pRoot==NULL)
return false;

path[flag++]=pRoot;
bool found=false;
if(pRoot==pNode)
{
found=true;
return found;
}
found=GetNodepath(pRoot->left,pNode,path,flag)||GetNodepath(pRoot->right,pNode,path,flag);
if(!found)
{
path[--flag]=NULL;

}
return found;
}

TreeNode*GetLastCommonNode(TreeNode* path1[15],TreeNode* path2[15])

{

TreeNode*pLast=NULL;
int i=0,j=0;

while(path1[i]!=NULL&&path2[j]!=NULL)
{
if(path1[i]==path2[j])
pLast=path1[i];
i++;
j++;
}
return pLast;
}

TreeNode* GetLastCommonparent(TreeNode* pRoot,TreeNode* pNode1,TreeNode* pNode2)
{
if(pRoot==NULL||pNode1==NULL||pNode2==NULL)
return NULL;
TreeNode* path1[15]={NULL};
int m=0;
GetNodepath(pRoot,pNode1,path1,m);
int i=0;
while(path1[i]!=NULL)
{
printf("%d ",path1[i]->value);
i++;
}

TreeNode* path2[15]={NULL};
GetNodepath(pRoot,pNode2,path2,m);
i=0;
cout<<endl;
while(path2[i]!=NULL)
{
printf("%d ",path2[i]->value);
i++;
}
return GetLastCommonNode(path1,path2);
}

void main()
{
TreeNode* p1 = new TreeNode(1);
TreeNode *p2 = new TreeNode(2);
TreeNode *p3 = new TreeNode(3);
TreeNode *p4 = new TreeNode(4);
TreeNode *p5 = new TreeNode(5);
TreeNode *p6 = new TreeNode(6);
TreeNode *p7 = new TreeNode(7);
TreeNode *p8 = new TreeNode(8);
TreeNode *p9 = new TreeNode(9);
TreeNode *p10 = new TreeNode(10);
p1->left = p2;
p1->right=p5;
p2->left = p3;
p2->right = p4;
p5->left = p6;
p5->right = p7;
p3->left = p8;
p3->right = p9;
p4->right = p10;
TreeNode *p;
p = GetLastCommonparent(p1 , p9 , p10);//p9和p10的最近公共祖先
if(p)
cout<<"两个节点最近公共祖先是 p"<<p->value<<endl;
else
cout<<"不存在公共祖先"<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: