PAT Advanced 1020 Tree Traversals (25) [⼆叉树的遍历,后序中序转层序]
题目
Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, you are supposed to output the level order traversal sequence of the corresponding binary tree.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (<=30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print in one line the level order traversal sequence of the corresponding binary tree. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.
Sample Input:
7
2 3 1 5 7 6 4 1 2 3 4 5 6 7
Sample Output:
4 1 6 3 5 7 2
题目分析
已知后序序列和中序序列,打印层序序列
解题思路
思路 01
- int in[n]记录中序序列,int post[n]记录后序序列
- 建树
2.1 post[n-1]为当前根结点root,在in中序序列中找到当前根结点root的位置i,i左边的元素为root的左子树所有结点,i右边元素为root的右子树所有结点
2.2 将root左子树所有结点作为后序序列继续查找其root和左右子树节点,将root右子树所有结点作为后序序列继续查找其root和左右子树结点 - 层序遍历树
思路 02(最优)
- int in[n]记录中序序列,int post[n]记录后序序列,node结构体中增加index属性记录树使用数组存储时的节点下标
- 前序遍历(利用中序和后序序列,依次找出根节点和其左右子树节点),设置其index,若某根节点index=i,则其左子节点index=2*i+1,其右子节点index=2*i+2
- 排序:根据index升序对所有结点排序
- 打印排序后的所有结点
思路 03
思路02中的index换为记录层号,对层号进行排序
注:不能使用sort,因为sort不稳定,导致同层顺序得不到保证,需要使用stable_sort()
知识点
- 已知中序序列和前序、后序、层序中任意一个序列,可唯一确定一棵二叉树
- 后序序列最后一个节点为根节点,该根节点将中序序列一分为二,左边为根节点左子树,右边为根节点右子树
- 树的层序遍历(借助队列)
- 根据后序序列和中序序列建树
- bfs层级遍历时,可以使用数组存储树的特点(即节点存储在下标i,则其左子节点下标为2i+1,右子节点下标为2i+2),之后对下标进行升序排序,遍历即为层序序列;
Code
Code 01
#include <iostream>
#include <queue>
using namespace std;
const int maxn=30;
int pre[maxn],in[maxn],post[maxn];
int n; // the number of nodes
struct node {
int data;
node* left;
node* right;
};
/*
后序序列和中序序列建树
*/
node * create(int postL,int postR,int inL,int inR) {
if(postL>postR)return NULL;
node * root=new node;
root->data=post[postR];
// 找到当前根节点在中序遍历中的位置
int i;
for(i=inL; i<=inR; i++) {
if(post[postR]==in[i])
break;
}
int numLeft=i-inL;
root->left=create(postL,postL+numLeft-1,inL,inL+numLeft-1);//inL+numLeft=i
root->right=create(postL+numLeft,postR-1,inL+numLeft+1,inR);//inL+numLeft=i
return root;
}
/*
树层序遍历
*/
int num=0;
void BFS(node * root) {
queue<node*> q;
q.push(root);
while(!q.empty()) {
node * now = q.front();
q.pop();
printf("%d",now->data);
num++;
if(num<n)printf(" ");
if(now->left!=NULL)q.push(now->left);
if(now->right!=NULL)q.push(now->right);
}
}
int main(int argc,char * argv[]) {
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%d",&post[i]);
for(int i=0; i<n; i++)
scanf("%d",&in[i]);
node* root=create(0,n-1,0,n-1);
BFS(root);
return 0;
}
Code 02(最优)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=30;
int n,in[maxn],post[maxn];
struct node {
int data;
int index;
};
vector<node> vns;
bool cmp(node &n1,node &n2){
return n1.index<n2.index;
}
void pre(int root,int start,int end,int index) {
if(start>end)return;
vns.push_back({post[root],index});
int i;
while(i<end&&in[i]!=post[root])i++;
pre(root-(end-i)-1,start,i-1,2*index+1);
pre(root-1,i+1,end,2*index+2);
}
int main(int argc,char *argv[]) {
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%d",&post[i]);
for(int i=0; i<n; i++)
scanf("%d",&in[i]);
pre(n-1,0,n-1,0);
sort(vns.begin(),vns.end(),cmp);
for(int i=0;i<vns.size();i++){
if(i!=0)printf(" ");
printf("%d",vns[i].data);
}
return 0;
}
Code 03
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=30;
int n,in[maxn],post[maxn];
struct node{
int d;
int l;
};
vector<node> pre;
void t_pre(int pl,int pr,int il,int ir,int level){
if(il>ir)return;
pre.push_back({post[pr],level});
int k=il;
while(k<n&&in[k]!=post[pr])k++;
t_pre(pl,pl+k-il-1,il,k-1,level+1);
t_pre(pl+k-il,pr-1,k+1,ir,level+1);
}
bool cmp(const node &a,const node &b){
return a.l<b.l;
}
int main(int argc,char * argv[]) {
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%d",&post[i]);
for(int i=0; i<n; i++)
scanf("%d",&in[i]);
t_pre(0,n-1,0,n-1,1);
stable_sort(pre.begin(),pre.end(),cmp);
printf("%d",pre[0]);
for(int i=1;i<n;i++)
printf(" %d",pre[i].d);
return 0;
}
PAT Advanced 1020 Tree Traversals (25) [⼆叉树的遍历,后序中序转层序]的更多相关文章
- PAT Advanced 1020 Tree Traversals (25 分)
1020 Tree Traversals (25 分) Suppose that all the keys in a binary tree are distinct positive integ ...
- PAT Advanced 1138 Postorder Traversal (25) [树的遍历,前序中序转后序]
题目 Suppose that all the keys in a binary tree are distinct positive integers. Given the preorder and ...
- 【PAT】1020 Tree Traversals (25)(25 分)
1020 Tree Traversals (25)(25 分) Suppose that all the keys in a binary tree are distinct positive int ...
- PAT 甲级 1020 Tree Traversals (25分)(后序中序链表建树,求层序)***重点复习
1020 Tree Traversals (25分) Suppose that all the keys in a binary tree are distinct positive intege ...
- PAT 甲级 1020 Tree Traversals (25 分)(二叉树已知后序和中序建树求层序)
1020 Tree Traversals (25 分) Suppose that all the keys in a binary tree are distinct positive integ ...
- 【PAT】1020. Tree Traversals (25)
Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and i ...
- 1020. Tree Traversals (25) ——树的遍历
//题目 通过后续遍历 中序遍历 得出一棵树 ,然后按树的层次遍历打印 PS:以前对于这种用指针的题目是比较头痛的,现在做了一些链表操作后,感觉也不难 先通过后续中序建一棵树,然后通过BFS遍历这棵树 ...
- PAT 甲级 1020 Tree Traversals (二叉树遍历)
1020. Tree Traversals (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Suppo ...
- PAT 甲级 1020 Tree Traversals
https://pintia.cn/problem-sets/994805342720868352/problems/994805485033603072 Suppose that all the k ...
随机推荐
- 【转】AutoMapper对象映射
什么是AutoMapper?AutoMapper是一个简单的小型库,用于解决一个看似复杂的问题 - 摆脱将一个对象映射到另一个对象的代码.这种类型的代码是相当沉闷和无聊的写,所以为什么不发明一个工具来 ...
- DataTable数据类型的一些操作 增加行、插入行、修改数据、修改列名、修改列顺序、计算、选取或删除行(列)、排序、某列distinct值 等
Datatable 这个数据类型在C#中涉及到对数据库读取时的用处还是挺大的,最近在处理一个报表开发时,一开始把所有的操作都放在sql 上面来做,就是我需要什么样的数据我就query出什么,但是这样其 ...
- 第一个flink application
导入maven依赖 需要注意的是,如果使用scala写程序,导入的依赖跟java是不一样的 Maven Dependencies You can add the following dependenc ...
- IO_课堂测试
IO_课堂测试 一,用户需求 英语的26 个字母的频率在一本小说中是如何分布的?某类型文章中常出现的单词是什么?某作家最常用的词汇是什么?<飘> 中最常用的短语是什么,等等. (1)要求1 ...
- 【pwnable.kr】fb
这是pwnable.kr的签到题,记录pwn入门到放弃的第一篇. ssh fd@pwnable.kr -p2222 (pw:guest) 题目很简单,登录上了ssh后,发现了3个文件:fd,fd.c, ...
- 17 ~ express ~ 分类的显示 ,修改 和 删除
一,前台显示 /views/admin/category.html {% extends 'layout.html' %} {% block main %} <ol class="br ...
- MFC中隐藏和显示光标的切换
函数原型:int ShowCursor(BOOL bShow): 参数: bShow:确定内部的显示计数器是增加还是减少,如果bShow为TRUE,则显示计数器增加1,如果bShow为FALSE,则计 ...
- POJ 1422 DAG最小路径覆盖
求无向图中能覆盖每个点的最小覆盖数 单独的点也算一条路径 这个还是可以扯到最大匹配数来,原因跟上面的最大独立集一样,如果某个二分图(注意不是DAG上的)的边是最大匹配边,那说明只要取两个端点只要一条边 ...
- UVA 10054 The Necklace 转化成欧拉回路
题意比较简单,给你n个项链碎片,每个碎片的两半各有一种颜色,最后要把这n个碎片串成一个项链,要求就是相邻碎片必须是同种颜色挨着. 看了下碎片总共有1000个,颜色有50种,瞬间觉得普通方法是无法在可控 ...
- mybatis的一对多和多对一的连接查询
实体类: package com.entity; import java.util.List; public class Dept { private Integer deptId; private ...