求两个节点最近的公共祖先
来源:互联网 发布:金山软件太原公司 编辑:程序博客网 时间:2024/05/08 06:03
(1)如果这棵树是二叉搜索树
二叉搜索树是排序过的,位于左子树的节点的值比当前节点的值小,而位于右子树的节点的值都比当前节点的值大。我们只需要从树的根节点开始和两个输入的节点进行比较。
(1)如果当前节点的值比两个节点的值都大,那么最近公共祖先一定在当前节点的左子树里。于是下一步遍历当前节点的左子树的节点。
(2)如果当前节点的值比两个节点的值都小,那么最近公共祖先一定在当前节点的右子树里,于是下一步遍历当前节点的右子树的节点。
(3)从根节点开始从上到下,第一个当前节点的值在两个节点值的中间,那么这个节点就是两个节点的最近公共祖先。
Node* BSTNearCommAncestor(Node* left, Node* right) { if (_root == NULL) { return NULL; } Node* cur = _root; while (cur) { if (cur->_data > left->_data && cur->_data > right->_data) { cur = cur->_left; } else if (cur->_data < left->_data && cur->_data < right->_data) { cur = cur->_right; } else { break; } } if (cur) { return cur; } return NULL; }
(2)如果这棵树不是二叉搜索树,并且这棵树是带有父节点的一棵树。
如果树中的每个节点都都有一个指向父节点的指针,那么这个问题可以转换成求两个链表的第一个公共的节点。每个节点的父亲一定是唯一的,那么从一个节点向上遍历,那么根节点一定会是一条链表的最后一个节点。那么两个节点向上一直到根节点,一定是两条相交的链表,这时候将问题看成是求两条链表相交的交点,那么这个点一定是两个节点的最近公共祖先。
Node* ParentNearCommAncestor(Node* left, Node* right) { if (_root == NULL) { return NULL; } vector<Node*> v1; vector<Node*> v2; while (left) { v1.push_back(left); left = left->_parent; } while (right) { v2.push_back(right); right = right->_parent; } Node* cur = NULL; int len = v1.size() < v2.size() ? v1.size() : v2.size(); while (len--) { if (v1[len] == v2[len]) { cur = v1[len]; } else { break; } } return cur; }
(3)如果这棵树不是二叉搜索树,树上的每一个节点也没有指向父亲节点的指针
方法一:
我们首先要得到一条从根节点到树中某一个节点的路径,这就要求在遍历的时候,有一个辅助内存来保存路径。然后我们求出两条路径下最后一个相同的公共节点,那么这个节点就是两个节点的最近公共祖先。
void GetNodePath(Node* root,const Node*& node, vector<Node*>& v, const bool& flag) { if (root == NULL || flag == true) { //空?节??点??或??者?是??已??经-找??到??node节??点??的??情??况?下?无T需??继??续?递?Y归??了?? return; } GetNodePath(root->_left, node, v,flag); GetNodePath(root->_right, node, v,flag); if (root == node || flag == true) { //找??到??这a个?节??点??或??者?是??已??经-找??到??这a个?节??点??路??径?上??的??其?他?节??点??需??要?a添???加??到??路??径?中D v.push_back(root); flag = true; } } Node* NearCommAncestor(Node* left, Node* right) { if (_root == NULL || left == NULL || right == NULL) { return; } vector<Node*> v1; GetNodePath(_root, left, v1, false); vector<Node*> v2; GetNodePath(_root, right, v2, false); int i = 0; while ((i < v1.size() - 1) && (i < v2.size() - 1)) { if (v1[i+1] != v2[i+1]) { break; } else { ++i; } } if ((i < v1.size() - 1) && (i < v2.size() - 1)) { return v1[i]; } return NULL; }
方法二:
我们可以后序遍历这棵二叉树,用left记录左子树返回的结果,用right记录右子树返回的结果。当左右子树都不为空的时候,返回当前节点表示已经找到了两个节点的最近公共祖先。
Node* _NearCommAncestor(Node* root, Node* node1, Node* node2) { if (root == NULL) { return NULL; } Node* left = _NearCommAncestor(root->_left, node1, node2); Node* right = _NearCommAncestor(root->_right, node1, node2); if (left && right) { return root; } if (root == node1) { return node1; } if (root == node2) { return node2; } if (left == NULL && right) { return right; } if (right == NULL && left) { return left; } } Node* NearCommAncestor(Node* node1, Node* node2) { return _NearCommAncestor(_root, node1, node2); }
阅读全文
0 0
- ~求两个节点的最近公共祖先~
- 求两个节点最近的公共祖先
- 求两个节点的最近公共祖先节点
- 求两个节点的最近公共祖先节点
- 求两个节点的最近公共祖先节点
- 求两个节点的最近公共祖先节点
- 如何求树中的两个节点的最近公共祖先?
- 求二叉树中两个节点的最近公共祖先
- 求二叉树中两个节点的最近公共祖先
- 求二叉树中两个节点的最近公共祖先
- 求二叉树中两个节点的最近公共祖先
- 求二叉树中两个节点的最近公共祖先
- 找树中两个节点的最近公共祖先
- 寻找两个节点的最近公共祖先
- 求树中两个节点的最近公共祖先
- 查找两个节点最近的公共祖先
- 求两个节点的最近祖先
- 求二叉树中两个节点的最近公共祖先节点
- Linux问题—设置“进程最大可打开的文件数”永久有效的方式
- 下列有关静态成员函数的描述中,正确的是:
- php+html 表单提交数据保存到mysql中
- Mybatis Generator的model生成中文注释,支持oracle和mysql(通过修改源码的方式来实现)
- android 一个视频播放的demo
- 求两个节点最近的公共祖先
- Spring Boot Druid 多数据源 Atomikos 分布式事务
- Android播放视频
- NOI2017 游记
- python之find all
- A
- linux设备模型之Class
- ros源码分析(7)—roslaunch .launch 文件
- SSM项目集成mybatis-plus