代码如下:
//三叉链struct treenode { int val; treenode *left; treenode *right;treenode *parent; treenode(int x) : val(x), left(null), right(null), parent(null) {}};class solution {public:treenode* lowestcommonancestor(treenode* root, treenode* p, treenode* q) {treenode* curp = p, *curq = q; //用于遍历p、q结点的祖先结点int lenp = 0, lenq = 0; //分别记录p、q结点各自的祖先结点个数//统计p结点的祖先结点个数while (curp != root){lenp++;curp = curp->parent;}//统计q结点的祖先结点个数while (curq != root){lenq++;curq = curq->parent;}//longpath和shortpath分别标记祖先路径较长和较短的结点treeno防暴天使 凯尔de* longpath = p, *shortpath = q;if (lenp <那一刻我长大了作文; lenq){longpath = q;shortpath = p;}//p、q结点祖先结点个数的差值int count = abs(lenp - lenq);//先让longpath往上走count个结点while (count--){longpath = longpath->parent;}//再让longpath和shortpath同时往上走,此时第一个相同的结点便是最近公共祖先结点while (longpath != shortpath){longpath = longpath->parent;shortpath = shortpath->parent;}return longpath; //返回最近公共祖先结点}};
代码如下:
//搜索二叉树struct treenode {int val;treenode *left;treenode *right;treenode(int x) : val(x), left(null), right(null) {}};class solution {public:treenode* lowestcommonancestor(treenode* root, treenode* p, treenode* q) {if (p->val == root->val || q->val == root->val) //p、q结点中某一个结点的值等于根结点的值,则根结点就是这两个结点的最近公共祖先return root;if (p->val < root->val&&q->val < root->val) //p、q结点的值都小于根结点的值,说明这两个结点的最近公共祖先在该树的左子树当中return lowestcommonancestor(root->left, p, q);el if (p->val > root->val&&q->val > root->val) //p、q结点的值都大于根结点的值,说明这两个结点的最近公共祖先在该树的右子树当中return lowestcommonancestor(root->right, p, q);el //p、q结点的值一个比根小一个比根大,说明根银行服务心得体会就是这两个结点的最近公共祖先return root;}};
代码如下:
//普通二叉树struct treenode {int val;treenode *left;treenode *right;treenode(int x) : val(x), left(null), right(null) {}};class solution {public:bool find(treenode* root, treenode* x){if (root == nullptr) //空树,查找失败return fal;if (root == x) //查找成功return true;return find(root->left, x) || find(root->right, x); //在左子树找到了或是右子树找到了,都说明该结点在该树当中}treenode* lowestcommonancestor(treenode* root, treenode* p, treenode* q) {if (p == root || q == root) //p、q结点中某一个结点为根结点,则根结点就是这两个结点的最近公共祖先return root;//判断p、q结点是否在左右子树bool ispinleft, ispinright, isqinleft, isqinright;ispinleft = find(root->left, p);ispinright = !ispinleft;isqinleft = find(root->left, q);isqinright = !isqinleft;if (ispinleft&&isqinleft) //p、q结点都在左子树,说明这两个结点的最近公共祖先也在左子树当中return lowestcommonancestor(root->left, p, q);el if (ispinright&&isqinright) //p、q结点都在右子树,说明这两个结点的最近公共祖先也在右子树当中return lowestcommonancestor(root->right, p, q);el //p、q结点一个在左子树一个在右子树,说明根就是这两个结点的最近公共祖先return root;}};
看着似乎不太好理解,来看看下面的动图演示:
代码如下:
//普通二叉树struct treenode {int val;treenode *left;treenode *right;treenode(int x) : val(x), left(null), right(null) {}};class solution {public:bool findpath(treenode* root, treenode* x, stack<treenode*>& path){if (root == nullptr)return fal;path.push(root); //该结点可能是路径当中的结点,先入栈if (root == x) //该结点是最终结点,查找结束return true;if (findpath(root->left, x, path)) //在该结点的左子树找到了最终实际问题与一元一次不等式结点,查找结束return true;if (findpath(root->right, x, path)) //在该结点的右子树找到了最终结点,查找结束return true;path.pop(); //在该结点的左右子树均没有找到最终结点,该结点不可能是路径当中的结点,该结点出栈return fal; //在该结点处查找失败}treenode* lowestcommonancestor(treenode* root, treenode* p, treenode* q) {stack<treenode*> ppath, qpath;findpath(root, p, ppath); //将从根到p结点的路径存放到ppath伤仲永的故事当中findpath(root, q, qpath); //将从根到q结点的路径存放到qpath当中//longpath和shortpath分别标记长路径和短路径stack<treenode*>* longpath = &ppath, *shortpath = &qpath;if (ppath.size() < qpath.size()){longpath = &qpath;shortpath = &ppath;}//让longpath先弹出差值个数据int count = longpath->size() - shortpath->size();while (count--){longpath->pop();}//longpath和shortpath一起弹数据,直到两个栈顶的结点相同while (longpath->top() != shortpath->top()){longpath->pop();shortpath->pop();}return longpath->top(); //返回这个相同的结点,即最近公共祖先}};
到此这篇关于漫画讲解c语言中最近公共祖先的三种类型的文章就介绍到这了,更多相关c语言 公共祖先内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!
本文发布于:2023-04-03 22:40:43,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/0114dd95f9f5dc730fdf933347e54c7f.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:漫画讲解C语言中最近公共祖先的三种类型.doc
本文 PDF 下载地址:漫画讲解C语言中最近公共祖先的三种类型.pdf
留言与评论(共有 0 条评论) |