二叉树两个节点求最近的公共祖先节点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
其中,parent用于处理t1是t2的祖先(或t2是t1的祖先)的情况。
在二叉树根结点的左子树和右子树中分别找输入的两个结点,如果两个结点都在左子树,遍历当前结点的左子树,如果两个结点都在右子树,遍历当前结点的右子树,直到一个在当前结点的左子树,一个在当前结点的右子树,返回当前结点就是最低的公共祖先结点。
求解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; }
相关文章推荐
- 利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离
- 利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离
- 利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离
- 求二叉树中两个节点的最近公共节点的C程序实现代码
- [转] 寻找二叉树中两个节点的最近的公共祖先
- 求二叉树的任意两个节点的最近公共祖先
- 在二叉树中查找两个节点的最近的公共祖先节点(有回溯指针)(NCA--nearest common ancestor)
- 求二叉树中两个节点的最近公共祖先节点
- 二叉树中两个节点的最近公共祖先节点方法全集
- 求两个节点的最近公共祖先多种解法&&判断一个节点是否在二叉树中
- 在二叉树中找到两个节点的最近公共祖先
- 二叉树中任意两个节点的最近公共祖先节点
- 寻找二叉树中两个节点的最近的公共祖先
- 在二叉树中,求任意两个节点的最近公共祖先(遍历的应用算法)
- 寻找二叉树两个节点的最近公共祖先
- 求解二叉树中两个节点的最近公共祖先(LCA)
- 给出一棵二叉树的根节点和其中两个不同的节点求出它们最近的公共祖先节点
- 寻找二叉树中两个节点的最近的公共祖先——迅雷笔试归来
- 在二叉树中查找两个节点的最近的公共祖先节点(无回溯指针)(NCA--nearest common ancestor)
- 二叉树中两个节点的最近公共祖先节点