520 钻石争霸赛 2021 7-8 浪漫侧影 (25 分)
Posted newnewvoid
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了520 钻石争霸赛 2021 7-8 浪漫侧影 (25 分)相关的知识,希望对你有一定的参考价值。
题目描述
“侧影”就是从左侧或者右侧去观察物体所看到的内容。例如上图中男生的侧影是从他右侧看过去的样子,叫“右视图”;女生的侧影是从她左侧看过去的样子,叫“左视图”。520 这个日子还在打比赛的你,也就抱着一棵二叉树左看看右看看了……我们将二叉树的“侧影”定义为从一侧能看到的所有结点从上到下形成的序列。例如下图这棵二叉树,其右视图就是 { 1, 2, 3, 4, 5 },左视图就是 { 1, 6, 7, 8, 5 }。
于是让我们首先通过一棵二叉树的中序遍历序列和后序遍历序列构建出一棵树,然后你要输出这棵树的左视图和右视图。
输入格式:
输入第一行给出一个正整数 N (≤20),为树中的结点个数。随后在两行中先后给出树的中序遍历和后序遍历序列。树中所有键值都不相同,其数值大小无关紧要,都不超过 int 的范围。
输出格式:
第一行输出右视图,第二行输出左视图,格式如样例所示。
输入样例:
8
6 8 7 4 5 1 3 2
8 5 4 7 6 3 2 1
输出样例:
R: 1 2 3 4 5
L: 1 6 7 8 5
解题思路:
- 本题和树的遍历的解题思路一样,根据一棵树的中序遍历和后序遍历求树的层序遍历的序列,只需输出每层第一个节点和最后一个节点。
- 根据中序遍历和后序遍历能够唯一的确定一棵树。首先在后序遍历中找出最后一个节点就是树的根节点,再从中序遍历找出根节点,左右两边分别是该节点的左子树和右子树,以此递归即可。
- 层序遍历数据使用STL中的deque记录,使用 deque.front() 和 deque.back() 即可输出队列中的首尾数据。
- 递归子树需要找到子树的根节点左子树为root - right + i - 1,右子树为root - 1。
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 35;
const int INF = 0x3f3f3f3f;
int n, maxlevel;
int in[MAXN], post[MAXN]; //存储中序遍历、后续遍历
deque<int> level[MAXN]; //存储层序遍历
void travel(int root, int left, int right, int deep)
{
//root 当前根节点
if(left > right){
return ;
}
int i = left;
while(i <= right && in[i] != post[root]){
//找到中序遍历中的根节点
i ++;
}
maxlevel = max(deep, maxlevel);
level[deep].push_back(post[root]);
travel(root - right + i - 1, left, i - 1, deep + 1); //遍历左子树
travel(root - 1, i + 1, right, deep + 1); //遍历右子树
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n;
for(int i = 0;i < n;i ++){
cin >> in[i];
}
for(int i = 0;i < n;i ++){
cin >> post[i];
}
maxlevel = 0; //记录最大深度
travel(n - 1, 0, n - 1, 1);
cout << "R:";
for(int i = 1;i <= maxlevel;i ++){
cout << " " << level[i].back();
}
cout << endl << "L:";
for(int i = 1;i <= maxlevel;i ++){
cout << " " << level[i].front();
}
return 0;
}
以上是关于520 钻石争霸赛 2021 7-8 浪漫侧影 (25 分)的主要内容,如果未能解决你的问题,请参考以下文章
520 钻石争霸赛 2021 7-8 浪漫侧影 (25 分)
520 钻石争霸赛 2021 7-8 浪漫侧影 (25 分)