十九、二叉树的最近的公共祖先
十九、二叉树的最近的公共祖先
文章目录
- 十九、二叉树的最近的公共祖先
- 题目描述
- 解题思路
- 上机代码:
题目描述
设顺序存储的二叉树中有编号为 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;
}
十九、二叉树的最近的公共祖先相关推荐
- python代码实现二叉树中最低的公共祖先
python代码实现二叉树中最低的公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结 ...
- 7-6 顺序存储的二叉树的最近的公共祖先问题 (10 分)
7-6 顺序存储的二叉树的最近的公共祖先问题 (10 分) 设顺序存储的二叉树中有编号为i和j的两个结点,请设计算法求出它们最近的公共祖先结点的编号和值. 输入格式: 输入第1行给出正整数n(≤100 ...
- 顺序存储的二叉树的最近的公共祖先问题
习题4.5 顺序存储的二叉树的最近的公共祖先问题 (25 分) 设顺序存储的二叉树中有编号为i和j的两个结点,请设计算法求出它们最近的公共祖先结点的编号和值. 输入格式: 输入第1行给出正整数n(≤1 ...
- 7-4 (小字辈) 7-5 (列出叶结点) 7-6 (顺序存储的二叉树的最近的公共祖先问题)
目录 7-4 小字辈 7-5 列出叶结点 7-6 顺序存储的二叉树的最近的公共祖先问题 总结: 7-4 小字辈 原题链接:题目详情 - 7-4 小字辈 (pintia.cn) 思路: 利用一维数组下标 ...
- 二叉树:最近的公共祖先 Lowest Common Ancestor of a Binary Tree
已知二叉树,求二叉树中给定的两个节点的最近公共祖先. 最近公共祖先: 两节点v与w的最近公共祖先u,满足在树上最低(离根最 远),且v,w两个节点都是u的子孙. 如上二叉树,6和8号节点的公共祖先有4 ...
- 7-5 顺序存储的二叉树的最近的公共祖先问题(25 分)
设顺序存储的二叉树中有编号为i和j的两个结点,请设计算法求出它们最近的公共祖先结点的编号和值. 输入格式: 输入第1行给出正整数n(≤),即顺序存储的最大容量:第2行给出n个非负整数,其间以空格分隔. ...
- 二叉树中的最近公共祖先
对于二叉树中任意两个结点p和q,可能存在如下的情形: p是q的祖先,此时p是p和q的最近公共祖先 q是p的祖先,此时q是p和q的最近公共祖先 p和q没有父子关系. 如果设p和q的最近公共祖先为x.如果 ...
- 【学透二叉树-二叉搜索树(二叉树)的最近公共祖先】
示例: 代码实现: class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q ...
- C++实现二叉树相关问题(先序遍历,中序遍历,后序遍历,层序遍历,搜索二叉树、平衡二叉树、满二叉树、完全二叉树的判断,最低公共祖先,二叉树的序列化和反序列化)
目录 题目一 二叉树递归和非递归遍历 题目二 如何完成二叉树的宽度(也叫层序)遍历(常见题目:求一棵二叉树的宽度) 题目四 如何判断一棵二叉树是搜索二叉树(BST)? 题目四 如何判断一棵二叉树是平衡 ...
最新文章
- FastJson常见问题
- golang错误处理机制(异常处理)
- HDU - 1560 DNA sequence
- Taro+react开发(24)--this.state和this.props
- Android系统架构开篇
- 排序算法总结(四)快速排序【QUICK SORT】
- php der格式 证书,php读取der格式证书乱码解决方法_PHP教程
- Atitit maven配置pom文件 配置法v2 t33 目录 1. Maven打包war原理	1 1.1. 在target目录生成war包ori目录。。。里面就是所有的资源	1 1.2. 去掉
- Android应用开发以及设计思想深度剖析(3)
- 防范项目中人员频繁变动的风险
- other|使用php调用aws sns服务发送短信通知
- Android Binder机制详解
- Python中while循环的基本用法
- 不小心格式化硬盘,重新分区了硬盘的恢复方法
- worldpress怎么增加登录注册按钮
- hoolilaw解读:在美国如何应对交通罚单
- CUDA入门和网络加速学习(二)
- win8系统 ps不能直接拖入图片的问题!解决方法
- 安卓应用程序加密,签名和发布
- Aspose.Words控件支持DOC,OOXML,RTF,HTML,OpenDocument,PDF,XPS,EPUB和其他格式