求二叉树中两个节点的最近公共祖先
2017-07-28 22:21
369 查看
要求考虑以下三种种情况,给出解决方案,并解决:
1:二叉树每个节点有parent(三叉链)
2:二叉树是搜索二叉树。
3:就是普通二叉树。(尽可能实现时间复杂度为O(N))
求两个结点的最近公共祖先有两种情况。
1、如果这两个结点不在一条线上,则它们就分别在最近的公共祖父的左右子树上。
2、如果这两个结点在一条线上,则它们之中深度最前的就是他们的最近的公共祖先。
1:三叉链。在这种情况下,我们可以分别用两个数据结构来保存两个节点到根节点的路径,然后通过对比,找到最近公共祖先。
2:二叉树是搜索二叉树,对于搜索树来说,左子树的节点都比根节点小,右子树的节点都比根节点大。根据搜索树这样的特征,我们可以有以下思路。
(1)如果一个节点比根节点小,另一个节点比根节点大, 则根节点为最近公共祖先;
(2)如果两个节点均比根节点小,则最近公共祖先在左子树;
(3)如果两个节点均比根节点大,则最近公共祖先在右子树。
有了这样的思路,我们可以通过递归,实现查找最近公共祖先。
3:普通二叉树
可以分别使用上面两种特殊情况的思想来处理普通二叉树
1:二叉树每个节点有parent(三叉链)
2:二叉树是搜索二叉树。
3:就是普通二叉树。(尽可能实现时间复杂度为O(N))
求两个结点的最近公共祖先有两种情况。
1、如果这两个结点不在一条线上,则它们就分别在最近的公共祖父的左右子树上。
2、如果这两个结点在一条线上,则它们之中深度最前的就是他们的最近的公共祖先。
1:三叉链。在这种情况下,我们可以分别用两个数据结构来保存两个节点到根节点的路径,然后通过对比,找到最近公共祖先。
/* //三叉链 struct Node { int _data; Node* _left; Node* _right; Node* _parent; Node(const int& x) : _data(x) , _left(NULL) , _right(NULL) , _parent(NULL) {} }; */ Node* GetLastestCommonAncestor4(Node* root, Node* x1, Node* x2) { assert(x1 && x2); if (root == NULL) return NULL; stack<Node*> s1; stack<Node*> s2; //x1 Node* cur1 = x1; while (cur1->_parent) { s1.push(cur1); cur1 = cur1->_parent; } //x2 Node* cur2 = x2; while (cur2->_parent) { s2.push(cur2); cur2 = cur2->_parent; } //走到这里,两个栈中分别保存了x1和x2到根节点的路径 while (s1.size() != s2.size()) { if (s1.size() > s2.size()) s1.pop(); else s2.pop(); } while (!s1.empty() && !s2.empty() && s1.top() != s2.top()) { s1.pop(); s2.pop(); } if (s1.top() == s2.top()) return s1.top(); return NULL; }
2:二叉树是搜索二叉树,对于搜索树来说,左子树的节点都比根节点小,右子树的节点都比根节点大。根据搜索树这样的特征,我们可以有以下思路。
(1)如果一个节点比根节点小,另一个节点比根节点大, 则根节点为最近公共祖先;
(2)如果两个节点均比根节点小,则最近公共祖先在左子树;
(3)如果两个节点均比根节点大,则最近公共祖先在右子树。
有了这样的思路,我们可以通过递归,实现查找最近公共祖先。
struct Node { int _data; Node* _left; Node* _right; Node(const int& x) : _data(x) , _left(NULL) , _right(NULL) {} }; Node* GetLastestCommonAncestor1(Node* root, Node* x1, Node* x2) { assert(x1&&x2); if (root == NULL) return NULL; if ((x1->_data <= root->_data&&x2->_data >= root->_data) || (x1->_data >= root->_data&&x2->_data <= root->_data)) return root; else if (x1->_data < root->_data&&x2->_data < root->_data) return GetLastestCommonAncestor1(root->_left, x1, x2); else return GetLastestCommonAncestor1(root->_right, x1, x1); }
3:普通二叉树
可以分别使用上面两种特殊情况的思想来处理普通二叉树
struct Node { int _data; Node* _left; Node* _right; Node(const int& x) : _data(x) , _left(NULL) , _right(NULL) {} }; //普通二叉树(搜索二叉树思想) bool IsInTree(Node* root, Node* x) { if (root == NULL) return false; if (root->_data == x->_data) return true; else return IsInTree(root->_left, x) || IsInTree(root->_right, x); } Node* GetLastestCommonAncestor2(Node* root, Node* x1, Node* x2) { assert(x1 && x2); if (root == NULL) return NULL; bool x1InLeft, x1InRight, x2InLeft, x2InRight; x1InLeft = IsInTree(root->_left, x1); x1InRight = IsInTree(root->_right, x1); assert(x1InLeft || x1InRight); x2InLeft = IsInTree(root->_left, x2); x2InRight = IsInTree(root->_right, x2); assert(x2InLeft || x2InRight); if ((x1InLeft && x2InRight) || (x1InRight && x2InLeft)) return root; else if (x1InLeft&&x2InLeft) return GetLastestCommonAncestor2(root->_left, x1, x2); else return GetLastestCommonAncestor2(root->_right, x2, x2); } //普通二叉树(三叉链方法的思想) bool GetNodePaths(Node* root, Node* x, stack<Node*>& s) { if (root == NULL) return; s.push(root); if (root == x) return true; bool inLeft = GetNodePaths(root->_left, x, s); if (inLeft) return true; bool inRight = GetNodePaths(root->_right, x, s); if (inRight) return true; s.pop(); return false; } Node* GetLastestCommonAncestor3(Node* root, Node* x1, Node* x2) { assert(x1&&x2); if (root == NULL) return NULL; stack<Node*> paths1, paths2; if (!GetNodePaths(root, x1, paths1) || !GetNodePaths(root, x2, paths2)) return NULL; while (paths1.size() != paths2.size()) { if (paths1.size() > paths2.size()) paths1.pop(); else paths2.pop(); } while (!paths1.empty() && !paths2.empty() && paths1.top() != paths2.top()) { paths1.pop(); paths2.pop(); } if (paths1.top() == paths2.top()) return paths1.top(); return NULL; }
相关文章推荐
- 235. Lowest Common Ancestor of a Binary Search Tree (求二叉树中两个节点的最近公共祖先)
- 二叉树两个节点求最近的公共祖先节点java代码实现
- 求二叉树的任意两个节点的最近公共祖先
- 求二叉树中两个节点的最近公共祖先
- 二叉树中两个节点的最近公共祖先节点
- day15之求二叉树中两个节点的最近公共祖先
- 二叉树系列---在二叉树中找到两个节点的最近公共祖先
- 二叉树中找到两个节点的最近公共祖先
- 二叉树中两个节点的最近公共祖先节点方法全集
- 二叉树中两个节点的最近公共祖先节点
- 判断一棵树是否是完全二叉树和求二叉树中两个节点的最近公共祖先——题集(十三)
- 求解二叉树中两个节点的最近公共祖先(LCA)
- 【学习点滴-数据结构-二叉树】求二叉树中某两个节点的最近公共祖先
- 二叉树--求二叉树中两个节点的最近公共祖先
- 二叉树中两个节点的最近公共祖先节点
- 利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离
- 求二叉树中两个节点的最近公共祖先
- 求二叉树中两个节点的最近公共祖先节点
- 利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离
- LCA问题:求二叉树中任意两个节点的最近公共祖先