求二叉树中两个节点的最近公共祖先
来源:互联网 发布:英雄杀探宝数据 编辑:程序博客网 时间:2024/05/16 11:40
比如:在如图这棵二叉树中,8和9的公共祖先是1,4和5的公共祖先是2,5和2的公共祖先是2。
在上述分析中,我们可以得出思路,本题解法可分为两种情况,(1)两个节点在根节点同侧 ,则它们的最近公共祖先可能是其中一个节点,也可能是在到两个节点的公共路径上。
(2)两个节点在根节点的不同侧,则它们的公共祖先只能是根节点。
同时,这棵树又分为三种情况:
(1)这棵树是搜索树
(2)这棵树中有三叉链
(3)它只是一棵普通的二叉树
template<class T>struct BinaryTreeNode{ T _data; BinaryTreeNode<T>* _left; BinaryTreeNode<T>* _right; BinaryTreeNode(const T& x) :_data(x) , _left(NULL) , _parent(NULL) , _right(NULL) {}};
1,这棵树是搜索树:根据搜索树的性质,它的所有左子树小于根节点,所有右子树大于根节点。
时间复杂度O(N)
Node* GetCommonAncestor(Node* root,Node* x1, Node* x2) { if (root == NULL) return NULL; else 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) GetCommonAncestor(root->_left, x1, x2); else if (x1->_data > root->_data && x2->_data > root->_data) GetCommonAncestor(root->_right, x1, x2); }
2,普通二叉树
时间复杂度O(N^2)
Node* GetCommonAncesstor(Node* root, Node* x1,Node*x2) { if (root == NULL) return NULL; if (x1 == NULL || x2 == NULL) return NULL; else { bool X1Inleft, X1Inright, X2Inleft, X2Inright; X1Inleft = GetCommonAncesstor(root->_left, x1); X1Inright = GetCommonAncesstor(root->_right, x1); assert(X1Inleft || X1Inright); X2Inleft = GetCommonAncesstor(root->_left, x1); X2Inright = GetCommonAncesstor(root->_right, x2); assert(X2Inleft || X2Inright); if (X1Inleft&&X2Inleft) return GetCommonAncesstor(root->_left, x1, x2); if (X1Inright&&X2Inright) return GetCommonAncesstor(root->_right, x1, x2); else return root; } }
优化为O(N)
Node* GetNodePath(Node* root,stack<Node*>& s, Node* x) { if (root) s.push(root); if (root->_data == x1->_data) return true; bool left = GetNodePath(root->_left, s, x); if (left) return true; bool right = GetNodePath(root->_right, s, x); if (right); return true; s.pop(); return false; } Node* GetNodeAncestor(Node* root, Node* x1, Node* x2) { if (NULL == root) return NULL; assert(x1 && x2); stack<Node*> s1, s2; if (!GetNodePaths(root, s1, x1) || !GetNodePaths(root, s2, x2)) return NULL; while (s1.size() != s2.size()) { if (s1.size() > s2.size()) s1.pop(); if (s1.size() < s2.size()) s2.pop(); } while (!s1.empty() && !s2.empty() && s1.top() != s2.top()) { s1.pop(); s2.pop(); } return s1.top(); }
3,这棵二叉树中有三叉链
template<class T>struct BinaryTreeNode{ T _data; BinaryTreeNode<T>* _left; BinaryTreeNode<T>* _right; BinaryTreeNode<T>* _parent; BinaryTreeNode(const T& x) :_data(x) , _left(NULL) , _parent(NULL) , _right(NULL) {}};
Node* GetCommenAncesstor(Node* root, Node* x1, Node* x2) { stack<Node*> s1; stack<Node*> s2; Node* cur1 = x1; Node* cur2 = x2; while (cur1->_parent) { if (cur1->_parent->_data == cur2->_data) return cur; else s1.push(cur1); cur1 = cur1->_parent; } while (cur2->_parent) { if (cur2->_parent->_data == cur1->_data) return cur1; else s2.push(cur2); cur2 = cur2->_parent; } Node* node = NULL; while (!s1.empty() && !s2.empty()) { if (s1.pop() == s2.pop()) node = s1.pop(); else return node; s1.pop(); s2.pop(); } return node; }
阅读全文
1 0
- 求二叉树中两个节点的最近公共祖先
- 求二叉树中两个节点的最近公共祖先
- 求二叉树中两个节点的最近公共祖先
- 求二叉树中两个节点的最近公共祖先
- 求二叉树中两个节点的最近公共祖先
- 二叉树中两个节点的最近公共祖先节点
- 二叉树中两个节点的最近公共祖先节点
- 二叉树中两个节点的最近公共祖先节点
- 二叉树中两个节点的最近公共祖先节点
- 求二叉树中两个节点的最近公共祖先节点
- 求二叉树中两个节点的最近公共祖先节点
- 二叉树--求二叉树中两个节点的最近公共祖先
- 二叉树中找到两个节点的最近公共祖先
- LCA问题:求二叉树中任意两个节点的最近公共祖先
- 求二叉树中两个指定节点的最近公共父祖先
- 面试题50:求二叉树中两个节点的最近公共祖先
- day15之求二叉树中两个节点的最近公共祖先
- 求二叉树中两个节点的最近公共祖先结点
- 安卓开发——为自己的app快速集成聊天功能
- Java虚拟机模型
- 刷题报告005 洛谷P1028数的计算
- 快使搭建zookeeper集群
- 《Unity 3D游戏客户端基础框架》系统设计
- 求二叉树中两个节点的最近公共祖先
- ZOJ Tempter of the Bone
- (3)队列
- 注释转换(C注释风格-C++注释风格)
- 优化术语定义
- 支付网关设计精要(Ping++ 联合创始人 赵宇)
- 汉诺塔 问题C/C++代码师范
- javaseday08(继承构造函数,final,抽象)
- 我有一个梦想