您的位置:首页 > 编程语言 > Java开发

二叉树两个节点求最近的公共祖先节点java代码实现

2017-08-26 17:26 429 查看
求二叉树中任意两个节点的最近公共祖先也称为LCA问题(Lowest Common Ancestor)。

求解LCA问题,应该首先考虑二叉树的特性和二叉树结点的结构,先看二叉树是否是搜索二叉树,若为普通二叉树则要考虑二叉树结点是否包含指向父结点的指针。

一、二叉搜索树

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

求解思路:

从树根开始,该节点的值为t,如果t大于t1和t2,说明t1和t2都位于t的左侧,所以它们的共同祖先必定在t的左子树中,从t.left开始搜索;

如果t小于t1和t2,说明t1和t2都位于t的右侧,那么从t.right开始搜索;

如果t1

public int query(Node t1, Node t2, Node t) {
int left = t1.value;
int right = t2.value;
Node parent = null;

if (left > right) {
int temp = left;
left = right;
right = temp;
}

while (true) {
if (t.value < left) {
parent = t;
t = t.right;
} else if (t.value > right) {
parent = t;
t = t.left;
} else if (t.value == left || t.value == right) {
return parent.value;
} else {
return t.value;
}
}
}


其中,parent用于处理t1是t2的祖先(或t2是t1的祖先)的情况。

二、普通二叉树(包含指向父结点的指针)

结点包含指向父结点的指针,这个问题可以转换成求两个链表的第一个公共结点,假设树结点中指向父结点的指针是parent,树的每一个叶结点开始都由一个指针parent串起来的链表,每个链表的尾结点就是树的根结点。那么输入的这两个结点位于链表上,它们的最低公共祖先结点刚好是这两个链表的第一个公共结点。

public int GetHigh(TreeNode root,TreeNode node){
int len=0;
while(node!=null){
len++;
node=node.parent;
}
return len;
}
public TreeNode GetLastCommonAncestor(TreeNode root, TreeNode node1, TreeNode node2)
{

if (root == null || node1 == null || node2 == null)
return null;

int len1 = GetHigh(root, node1);//一个链表的高度
int len2 = GetHigh(root, node2);//另一个链表的高度
//寻找两个链表的第一个交点
if(len1 != len2)
{
if (len1 < len2) {
for(int i=0;i<len2-len1;i++){
node2=node2.parent;
}
}
else {
for(int i=0;i<len1-len2;i++){
node1=node1.parent;
}
}
}

while (node1 && node2 && node1 != node2)
{
node1 = node1.parent;
node2 = node2.parent;
}

if (node1 == node2)
return node1;
else
return null;
}


三、普通二叉树(不包含指向父结点的指针)

求解思路:

在二叉树根结点的左子树和右子树中分别找输入的两个结点,如果两个结点都在左子树,遍历当前结点的左子树,如果两个结点都在右子树,遍历当前结点的右子树,直到一个在当前结点的左子树,一个在当前结点的右子树,返回当前结点就是最低的公共祖先结点。

public boolean IsNodeInTree(TreeNode pRoot, TreeNode pNode)
{
if (pRoot == null || pNode == null)
return false;
if (pNode == pRoot)
return true;
if (IsNodeInTree(pRoot.left, pNode) || IsNodeInTree(pRoot.right, pNode))
return true;
return false;
}
public TreeNode GetCommonAncestor(TreeNode pRoot, TreeNode node1, TreeNode node2)
{
if (pRoot == null)
return null;
if (node1 == pRoot && IsNodeInTree(pRoot, node2) || node2 == pRoot && IsNodeInTree(pRoot, node1))
return pRoot;

boolean node1left = IsNodeInTree(pRoot.left, node1);
boolean node1right = IsNodeInTree(pRoot.right, node1);
boolean node2left = IsNodeInTree(pRoot.left, node2);
boolean node2right = IsNodeInTree(pRoot.right, node2);
if (node1left && node2right || node1right && node2left)
return pRoot;
if (node1left && node2left)
return GetCommonAncestor(pRoot.left, node1, node2);
if (node1right && node2right)
return GetCommonAncestor(pRoot.right, node1, node2);
return null;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐