求树中两个节点的最近公共祖先
2015-06-19 16:09
274 查看
(编程之美)求树中两个节点的最短公共祖先。
情况一:二叉搜索树
二叉搜索树都是排序过的,位于左子树的节点都比父节点小,而位于右子树上面的节点都比父节点大。
如果当前节点的值比两个结点 的值都大,那么最低的共同的父节点一定是在当前节点的左子树中,于是下一步遍历当前节点的左子节点。
如果当前节点的值比两个结点的值都小,那么最低的共同的父节点一定是在当前节点的右子树中,于是下一步遍历当前节点的右子节点。
这样从上到下,找到的第一个在两个输入结点的值之间的节点,就是最低的公共祖先。
情况二:这是一颗普通的树,但是有指向父节点的指针
题目等价于求解两个链表的第一个公共节点问题
情况三:这是一颗普通的树,没有指向父节点的指针
用两个链表分别保存从根节点到输入的两个结点的路径,然后把问题转换成两个链表的最后公共节点。
代码如下:
情况一:二叉搜索树
二叉搜索树都是排序过的,位于左子树的节点都比父节点小,而位于右子树上面的节点都比父节点大。
如果当前节点的值比两个结点 的值都大,那么最低的共同的父节点一定是在当前节点的左子树中,于是下一步遍历当前节点的左子节点。
如果当前节点的值比两个结点的值都小,那么最低的共同的父节点一定是在当前节点的右子树中,于是下一步遍历当前节点的右子节点。
这样从上到下,找到的第一个在两个输入结点的值之间的节点,就是最低的公共祖先。
情况二:这是一颗普通的树,但是有指向父节点的指针
题目等价于求解两个链表的第一个公共节点问题
情况三:这是一颗普通的树,没有指向父节点的指针
用两个链表分别保存从根节点到输入的两个结点的路径,然后把问题转换成两个链表的最后公共节点。
代码如下:
#include<iostream> #include<list> using namespace std; struct TreeNode { int value; TreeNode* left; TreeNode* right; TreeNode(int nvalue):value(nvalue),left(NULL),right(NULL){}; }; bool GetNodepath(TreeNode* pRoot,TreeNode* pNode,TreeNode*path[15],int flag) { if(pRoot==NULL) return false; path[flag++]=pRoot; bool found=false; if(pRoot==pNode) { found=true; return found; } found=GetNodepath(pRoot->left,pNode,path,flag)||GetNodepath(pRoot->right,pNode,path,flag); if(!found) { path[--flag]=NULL; } return found; } TreeNode*GetLastCommonNode(TreeNode* path1[15],TreeNode* path2[15]) { TreeNode*pLast=NULL; int i=0,j=0; while(path1[i]!=NULL&&path2[j]!=NULL) { if(path1[i]==path2[j]) pLast=path1[i]; i++; j++; } return pLast; } TreeNode* GetLastCommonparent(TreeNode* pRoot,TreeNode* pNode1,TreeNode* pNode2) { if(pRoot==NULL||pNode1==NULL||pNode2==NULL) return NULL; TreeNode* path1[15]={NULL}; int m=0; GetNodepath(pRoot,pNode1,path1,m); int i=0; while(path1[i]!=NULL) { printf("%d ",path1[i]->value); i++; } TreeNode* path2[15]={NULL}; GetNodepath(pRoot,pNode2,path2,m); i=0; cout<<endl; while(path2[i]!=NULL) { printf("%d ",path2[i]->value); i++; } return GetLastCommonNode(path1,path2); } void main() { TreeNode* p1 = new TreeNode(1); TreeNode *p2 = new TreeNode(2); TreeNode *p3 = new TreeNode(3); TreeNode *p4 = new TreeNode(4); TreeNode *p5 = new TreeNode(5); TreeNode *p6 = new TreeNode(6); TreeNode *p7 = new TreeNode(7); TreeNode *p8 = new TreeNode(8); TreeNode *p9 = new TreeNode(9); TreeNode *p10 = new TreeNode(10); p1->left = p2; p1->right=p5; p2->left = p3; p2->right = p4; p5->left = p6; p5->right = p7; p3->left = p8; p3->right = p9; p4->right = p10; TreeNode *p; p = GetLastCommonparent(p1 , p9 , p10);//p9和p10的最近公共祖先 if(p) cout<<"两个节点最近公共祖先是 p"<<p->value<<endl; else cout<<"不存在公共祖先"<<endl; }
相关文章推荐
- 创建SQLAlchemy的ORM类的基类(一)
- Java设计模式——类的关系
- UVA 10604--Chemical Reaction+记忆化搜索
- 2016年华为 软开实习生招聘面经(机试面试)
- Tomcat实现HTTPS&SSL访问
- ubuntu 压缩软件
- Collections集合(对象集合)的排序
- java future模式举例
- 制作根文件系统
- git flow的使用
- php数组中删除元素,再重新索引
- swift文件上传及表单提交
- 65個技巧性回答 绝对值得收藏
- 黑马程序员--JAVA基础知识学习笔记
- 我眼中的 Docker(一)docker、vm、lxc
- 生成条形码和二维码并实现打印的功能
- http://blog.csdn.net/jiahui524
- 第16周-异常处理和命名空间-项目3-max带来的冲突
- 【php】利用新浪api接口与php获取远程数据的方法,获取IP地址,并获取相应的IP归属地
- 安卓中的线程