十九、二叉树的最近的公共祖先

文章目录

  • 十九、二叉树的最近的公共祖先
    • 题目描述
    • 解题思路
    • 上机代码:

题目描述

设顺序存储的二叉树中有编号为 i 和 j 的两个结点,请设计算法求出它们最近的公共祖先结点的编号和值。

输入:

​ 输入第1行给出正整数n(≤1000),即顺序存储的最大容量;
第2行给出n个非负整数,其间以空格分隔。其中0代表二叉树中的空结点(如果第1个结点为0,则代表一棵空树);
第3行给出一对结点编号 i 和 j 。
题目保证输入正确对应一棵二叉树,且1≤ i,j ≤n。

输出:

如果i或j对应的是空结点,则输出:ERROR: T[x] is NULL,其中 x 是 i 或 j 中先发现错误的那个编号;否则在一行中输出编号为 i 和 j 的两个结点最近的公共祖先结点的编号和值,其间以一个空格分隔。

测试输入 期待的输出 时间限制 内存限制 额外进程
测试用例 1 15
4 3 5 1 10 0 7 0 2 0 9 0 0 6 8
11 4
2 3 1秒 64M 0
测试用例 2 15
4 3 5 1 0 0 7 0 2 0 0 0 0 6 8
12 8
ERROR: T[12] is NULL 1秒 64M 0
测试用例 3 15
4 3 5 1 0 0 7 0 2 0 0 0 0 6 8
8 12
ERROR: T[8] is NULL 1秒 64M 0

解题思路

求解结点的最近公共祖先(Least Common Ancestors,LCA),做法如下:

从根节点开始遍历

  • 如果node1和node2中的任一个和root匹配,那么root就是最低公共祖先。
  • 如果都不匹配,则分别递归左、右子树,
  • 如果有一个节点出现在左子树,并且另一个节点出现在右子树,则root就是最低公共祖先.
  • 如果两个节点都出现在左子树,则说明最低公共祖先在左子树中,否则在右子树。

注意,如果 i、j 是空节点,直接输出 ERROR。

上机代码:

在二叉树的存储结构中,data是输入序列中二叉树结点的值,vis是按照完全二叉树的顺序对应二叉树的结点的编号。通过 vis 可以更简单地判断二叉树向下查找时有没有超出边界,同时通过打印 vis 可以知道二叉树有没有正确地建立。

下面代码中的两个函数 in_sequence()print(),通过中序遍历打印 data 和 vis 的值,我借此来判断二叉树有没有正确建立,与本题关系不大。

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef struct NODE
{int data;  //结点的值int vis;  //结点的序号struct NODE *lchild;struct NODE *rchild;
}node, *Tree;queue<Tree>q;
int n = 0, a[1010];//数组存储结点信息void createTree()
{int flag = 0;Tree T, N;T = (Tree)malloc(sizeof(node));cin >> n;for (int i = 1; i <= n; i++)cin >> a[i];//建立二叉树while (!q.empty()){flag++;T = q.front();q.pop();T->data = a[flag];T->vis = flag;N = (Tree)malloc(sizeof(node));N->data = -1;N->vis = -1;//没有访问过T->lchild = N;q.push(N);N = (Tree)malloc(sizeof(node));N->data = -1;N->vis = -1;T->rchild = N;q.push(N);if (flag == n)break;}
}
void in_sequence(Tree T)
{if (T->data != -1){in_sequence(T->lchild);cout << T->data << " ";in_sequence(T->rchild);}return;
}
void print(Tree T)
{if (T->data != -1){print(T->lchild);cout << T->vis << " ";print(T->rchild);}return;
}
Tree LCA(Tree T,int u,int v)
{if (T->vis == -1)//超出搜索范围return T;if (T->vis == u || T->vis == v)//找到u,v的值return T;Tree cur = (Tree)malloc(sizeof(node));//递归左右子树Tree left_lca = (Tree)malloc(sizeof(node));left_lca = LCA(T->lchild, u, v);if (left_lca->vis != -1){cur = LCA(left_lca->lchild, u, v);if (cur->vis != -1)cur = LCA(left_lca->rchild, u, v);if ((cur->vis == u && left_lca->vis == v) || (cur->vis == v && left_lca->vis == u))return T;}Tree right_lca = (Tree)malloc(sizeof(node));right_lca = LCA(T->rchild, u, v);if (right_lca->vis != -1){cur = LCA(right_lca->lchild, u, v);if (cur->vis != -1)cur = LCA(right_lca->rchild, u, v);if ((cur->vis == u && right_lca->vis == v) || (cur->vis == v && right_lca->vis == u))return T;}if (left_lca->vis != -1 && right_lca->vis != -1)return T;if (left_lca->vis == -1)return right_lca;elsereturn left_lca;
}
int main()
{memset(a, -1, sizeof(a));Tree bit;bit = (Tree)malloc(sizeof(node));q.push(bit);createTree();/*in_sequence(bit);printf("\n");print(bit);printf("\n");*/int u = 0, v = 0;cin >> u >> v;if (a[u]==0){printf("ERROR: T[%d] is NULL\n", u);//system("pause");return 0;}else if (a[v]==0){printf("ERROR: T[%d] is NULL\n", v);//system("pause");return 0;}else{Tree tmp = (Tree)malloc(sizeof(node));tmp=LCA(bit, u, v);printf("%d %d\n", tmp->vis, tmp->data);}//system("pause");return 0;
}

十九、二叉树的最近的公共祖先相关推荐

  1. python代码实现二叉树中最低的公共祖先

    python代码实现二叉树中最低的公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结 ...

  2. 7-6 顺序存储的二叉树的最近的公共祖先问题 (10 分)

    7-6 顺序存储的二叉树的最近的公共祖先问题 (10 分) 设顺序存储的二叉树中有编号为i和j的两个结点,请设计算法求出它们最近的公共祖先结点的编号和值. 输入格式: 输入第1行给出正整数n(≤100 ...

  3. 顺序存储的二叉树的最近的公共祖先问题

    习题4.5 顺序存储的二叉树的最近的公共祖先问题 (25 分) 设顺序存储的二叉树中有编号为i和j的两个结点,请设计算法求出它们最近的公共祖先结点的编号和值. 输入格式: 输入第1行给出正整数n(≤1 ...

  4. 7-4 (小字辈) 7-5 (列出叶结点) 7-6 (顺序存储的二叉树的最近的公共祖先问题)

    目录 7-4 小字辈 7-5 列出叶结点 7-6 顺序存储的二叉树的最近的公共祖先问题 总结: 7-4 小字辈 原题链接:题目详情 - 7-4 小字辈 (pintia.cn) 思路: 利用一维数组下标 ...

  5. 二叉树:最近的公共祖先 Lowest Common Ancestor of a Binary Tree

    已知二叉树,求二叉树中给定的两个节点的最近公共祖先. 最近公共祖先: 两节点v与w的最近公共祖先u,满足在树上最低(离根最 远),且v,w两个节点都是u的子孙. 如上二叉树,6和8号节点的公共祖先有4 ...

  6. 7-5 顺序存储的二叉树的最近的公共祖先问题(25 分)

    设顺序存储的二叉树中有编号为i和j的两个结点,请设计算法求出它们最近的公共祖先结点的编号和值. 输入格式: 输入第1行给出正整数n(≤),即顺序存储的最大容量:第2行给出n个非负整数,其间以空格分隔. ...

  7. 二叉树中的最近公共祖先

    对于二叉树中任意两个结点p和q,可能存在如下的情形: p是q的祖先,此时p是p和q的最近公共祖先 q是p的祖先,此时q是p和q的最近公共祖先 p和q没有父子关系. 如果设p和q的最近公共祖先为x.如果 ...

  8. 【学透二叉树-二叉搜索树(二叉树)的最近公共祖先】

    示例: 代码实现: class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q ...

  9. C++实现二叉树相关问题(先序遍历,中序遍历,后序遍历,层序遍历,搜索二叉树、平衡二叉树、满二叉树、完全二叉树的判断,最低公共祖先,二叉树的序列化和反序列化)

    目录 题目一 二叉树递归和非递归遍历 题目二 如何完成二叉树的宽度(也叫层序)遍历(常见题目:求一棵二叉树的宽度) 题目四 如何判断一棵二叉树是搜索二叉树(BST)? 题目四 如何判断一棵二叉树是平衡 ...

最新文章

  1. FastJson常见问题
  2. golang错误处理机制(异常处理)
  3. HDU - 1560 DNA sequence
  4. Taro+react开发(24)--this.state和this.props
  5. Android系统架构开篇
  6. 排序算法总结(四)快速排序【QUICK SORT】
  7. php der格式 证书,php读取der格式证书乱码解决方法_PHP教程
  8. Atitit maven配置pom文件 配置法v2 t33 目录 1. Maven打包war原理 1 1.1. 在target目录生成war包ori目录。。。里面就是所有的资源 1 1.2. 去掉
  9. Android应用开发以及设计思想深度剖析(3)
  10. 防范项目中人员频繁变动的风险
  11. other|使用php调用aws sns服务发送短信通知
  12. Android Binder机制详解
  13. Python中while循环的基本用法
  14. 不小心格式化硬盘,重新分区了硬盘的恢复方法
  15. worldpress怎么增加登录注册按钮
  16. hoolilaw解读:在美国如何应对交通罚单
  17. CUDA入门和网络加速学习(二)
  18. win8系统 ps不能直接拖入图片的问题!解决方法
  19. 安卓应用程序加密,签名和发布
  20. Aspose.Words控件支持DOC,OOXML,RTF,HTML,OpenDocument,PDF,XPS,EPUB和其他格式

热门文章

  1. 如何用 Netty 设计一个百万级推送服务?
  2. Go语言入门——dep入门
  3. Prometheus 初探
  4. JVM:堆中对象的创建?定位?可达性?
  5. ci框架去除index.php,ci框架如何隐藏index.php
  6. html5g与h5的区别,H5是什么?
  7. 【Castell】安全联锁提升UPS设备维护管理水平
  8. 亚马逊AWS 数据中心起火,致 5 人死亡、50 人受伤
  9. 直流UPS与传统UPS系统节能分析
  10. 计算机设置从光盘启动怎么办,设置BIOS从光盘启动教程