PAT Advance 1119 Pre- and Post-order Traversals (30) [树的遍历,前序后序转中序]
题目
Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree can be determined by a given pair of postorder and inorder traversal sequences, or preorder and inorder traversal sequences. However, if only the postorder and preorder traversal sequences are given, the corresponding tree may no longer be unique. Now given a pair of postorder and preorder traversal sequences, you are supposed to output the corresponding inorder traversal sequence of the tree. If the tree is not unique, simply output any one of them.
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 preorder sequence and the third line gives the postorder sequence. All the numbers in a line are separated by a space.
Output Specification:
For each test case, first printf in a line “Yes” if the tree is unique, or “No” if not. Then print in the next line the inorder traversal sequence of the corresponding binary tree. If the solution is not unique, any answer would do. It is guaranteed that at least one solution exists. 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 1:
7
1 2 3 4 6 7 5
2 6 7 4 5 3 1
Sample Output 1:
Yes
2 1 6 4 7 3 5
Sample Input 2:
4
1 2 3 4
2 4 3 1
Sample Output 2:
No
2 1 3 4
题目分析
已知前序和后序,打印中序
- 若中序唯一,打印Yes和唯一中序序列
- 若中序不唯一,打印No和任意一个中序序列
注:如何判断中序是否唯一?
在前序序列中,如果当前右子树根节点(当前后序序列倒数第二个节点)左边只有一个节点,则说明当前右子树根节点既可以为其父节点的左孩子节点,也可为其父节点的右孩子节点
如:前序序列1 2 3 4,后序序列2 4 3 1
第一轮:前序序列为1 2 3 4,后序序列为2 4 3 1。后序序列最后一个节点1为根节点,后序序列倒数第二个节点3为1的右子树根节点,查找其在前序序列中其左边有两个节点1,2,则1为根节点,2为1的左子节点,3为1的右子节点
左递归:(处理第一轮中的左子树):前序序列为2,后序序列为2
右递归:(处理第一轮中的右子树):前序序列为3 4,后序序列为4 3。后序序列最后一个节点3为本轮根节点,后序序列倒数第二个节点4为3的右子树根节点,查找其在前序序列中其左边只有一个节点3,3为根节点,4既可以为3的左子节点也可以为3的右子节点(二叉树不唯一,即:中序序列不唯一)
解题思路
思路 01
- 后序序列倒数第一个节点为当前根节点,后序序列倒数第二个节点为当前根节点的右子树根节点
- 先处理当前根节点的左子树,找到最左节点后添加到in中序序列中
- 将1中最左节点的根节点添加到in中序序列中
- 再处理当前根节点的右子树,将其看做一棵树,处理方式同步骤1,2,3(找最左节点及其根节点并处理其右子树)
注:
第一轮
preOrder: 1 2 3 4 6 7 5
postOrder: 2 6 7 4 5 3 1
当前根节点为1,右子树根节点为3,由其在前序序列中的位置可看出,右子树节点包含:3 4 6 7 5,左子树只有一个节点为2
将2入中序序列,之后将1入中序序列(此刻中序序列为:2 1)
第二轮
preOrder: 3 4 6 7 5
postOrder: 6 7 4 5 3
当前根节点为3,右子树只有一个节点为5,由其在前序序列中的位置可看出,左子树根节点为4,左子树节点包含:4 6 7
----递归(处理左子树):找最左节点为6,其根为4,最左节点的父节点的右节点为叶子节7,依次入中序序列(此刻中序序列为:2 1 6 4 7)
继续处理:根节点3入中序序列,其唯一右子树节点5入中序序列(此刻中序序列为:2 1 6 4 7 3 5)
思路 02(容易理解)
- 后序序列倒数第一个节点为当前根节点,后序序列倒数第二个节点为当前根节点的右子树根节点
- 递归查找当前根节点的左右子节点
- 若遇到右子节点前只有一个根节点的情况,说明该右子节点也可为其根节点的左子节点(即:二叉树不唯一,中序序列不唯一),unique标识置为false,并将该节点假设为其根节点的右子节点处理
易错点
1. 最后输出完毕后,必须打印一个换行,否则所有测试点格式错误
Code
Code 01
#include <iostream>
#include <vector>
using namespace std;
const int maxn = 30;
int n,pre[maxn],post[maxn],index;
bool unique=true;
vector<int> in;
void inOrder(int preL,int preR,int postL,int postR) {
// if(preL>preR)return;
if(preL==preR) {
in.push_back(pre[preL]);
return;
}
if(pre[preL]==post[postR]) {
int k=preL+1;
while(k<preR&&pre[k]!=post[postR-1])k++;
if(k-preL>1) {
inOrder(preL+1,k-1,postL,postL+(k-preL-1)-1);
} else {
unique=false;
}
in.push_back(post[postR]);
inOrder(k,preR,postL+(k-preL-1),postR-1);
}
}
int main(int argc,char * argv[]) {
scanf("%d",&n);
for(int i=0; i<n; i++) scanf("%d",&pre[i]);
for(int i=0; i<n; i++) scanf("%d",&post[i]);
inOrder(0,n-1,0,n-1);
printf("%s\n%d", unique == true ? "Yes" : "No", in[0]);
for (int i = 1; i < in.size(); i++)
printf(" %d", in[i]);
printf("\n"); //测试发现:最后必须输出换行,否则全部格式错误
return 0;
}
Code 02(容易理解)
#include <iostream>
using namespace std;
const int maxn = 30;
int n,pre[maxn],post[maxn],index;
bool unique=true;
struct node {
int data;
node * left;
node * right;
};
node * create(int preL,int preR,int postL,int postR) {
if(preL>preR)return NULL;
node * root = new node;
root->data=post[postR];
root->left=NULL;
root->right=NULL;
if(preL==preR)return root;
int k=preL+1;
while(k<=preR&&pre[k]!=post[postR-1])k++;
if(k-preL>1) {
root->left=create(preL+1,k-1,postL,postL+(k-preL-1)-1);
root->right=create(k,preR,postL+(k-preL-1),postR-1);
} else {
unique = false;
root->right=create(k,preR,postL+(k-preL-1),postR-1);
}
return root;
}
void inOrder(node * root) {
if(root==NULL)return;
inOrder(root->left);
if(index<n-1)printf("%d ",root->data);
else printf("%d\n",root->data); //测试发现:最后欧必须输出换行,否则全部格式错误
index++;
inOrder(root->right);
}
int main(int argc, char * argv[]) {
scanf("%d",&n);
for(int i=0; i<n; i++) scanf("%d",&pre[i]);
for(int i=0; i<n; i++) scanf("%d",&post[i]);
node * root = create(0,n-1,0,n-1);
printf("%s\n",unique?"Yes":"No");
inOrder(root);
return 0;
}
PAT Advance 1119 Pre- and Post-order Traversals (30) [树的遍历,前序后序转中序]的更多相关文章
- PAT Advanced 1151 LCA in a Binary Tree (30) [树的遍历,LCA算法]
题目 The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both ...
- PAT A 1119. Pre- and Post-order Traversals (30)【二叉树遍历】
No.1119 题目:由前序后序二叉树序列,推中序,判断是否唯一后输出一组中序序列 思路:前序从前向后找,后序从后向前找,观察正反样例可知,前后序树不唯一在于单一子树是否为左右子树. 判断特征:通过查 ...
- 【PAT甲级】1119 Pre- and Post-order Traversals(前序后序转中序)
[题目链接] [题意] 根据二叉树的前序和后序序列,如果中序序列唯一,输出Yes,如果不唯一输出No,并输出这个中序序列. [题解] 众所周知,二叉树是不能够根据前序和中序建立的,为什么呢?首先需要明 ...
- PAT 甲级 1020 Tree Traversals (25 分)(二叉树已知后序和中序建树求层序)
1020 Tree Traversals (25 分) Suppose that all the keys in a binary tree are distinct positive integ ...
- PAT Advanced 1020 Tree Traversals (25) [⼆叉树的遍历,后序中序转层序]
题目 Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder an ...
- PAT Advanced 1053 Path of Equal Weight (30) [树的遍历]
题目 Given a non-empty tree with root R, and with weight Wi assigned to each tree node Ti. The weight ...
- PAT甲题题解-1119. Pre- and Post-order Traversals (30)-(根据前序、后序求中序)
(先说一句,题目还不错,很值得动手思考并且去实现.) 题意:根据前序遍历和后序遍历建树,输出中序遍历序列,序列可能不唯一,输出其中一个即可. 已知前序遍历和后序遍历序列,是无法确定一棵二叉树的,原因在 ...
- PAT 甲级 1021 Deepest Root (并查集,树的遍历)
1021. Deepest Root (25) 时间限制 1500 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue A graph ...
- 1020. Tree Traversals (25) ——树的遍历
//题目 通过后续遍历 中序遍历 得出一棵树 ,然后按树的层次遍历打印 PS:以前对于这种用指针的题目是比较头痛的,现在做了一些链表操作后,感觉也不难 先通过后续中序建一棵树,然后通过BFS遍历这棵树 ...
随机推荐
- SignalTap II Logic Analyzer 无法观测到信号?
在Quartus SignalTap 工具中加入信号,发现加入的信号变成红色,如图所示的data_slave[7..0]: 这样的信号是没有办法观测的,不会根据SignalTap 的Clock和Tri ...
- (分治)输出前m大的数。。。
描述给定一个数组包含n个元素,统计前m大的数并且把这m个数从大到小输出.输入第一行包含一个整数n,表示数组的大小.n < 100000.第二行包含n个整数,表示数组的元素,整数之间以一个空格分开 ...
- Golang的标识符命名规则
Golang的标识符命名规则 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.关键字 1>.Go语言有25个关键字 Go语言的25个关键字如下所示: break,defau ...
- Fedora-19安装texlive2013并配置中文
参考博文: http://blog.csdn.net/longerzone/article/details/8129124 之前通过yum install安装了texlive,不过在使用过程中老是报 ...
- hibernate字段值无法保存
通过hibernate对Blogstorage对象进行保存操作,filepath属性的值无论设置多少遍都保存不进去 后来发现是 Blogstorage.hbm.xml 里面根本没有配置filepath ...
- select2 智能补全模糊查询select2的下拉选择框使用
我们在上篇文章中已经在SpringMVC基础框架的基础上应用了BootStrap的后台框架,在此基础上记录select2的使用. 应用bootstrap模板 基础项目源码下载地址为: SpringMV ...
- 干货分享:学术Essay写作流程及写作技巧详解
Academic essay是指留学生作业中的一种,其范围非常广泛,可以是任何一种话题.而学术essay主要是指其中比较正式的.客观的话题,有明确的研究目的与研究对象.例如“Research on t ...
- 腾讯云服务器上搭建 2.176.3-1.1 版本的Jenkins,jdk 11
[root@VM_0_12_centos fonts]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) [root@VM_0 ...
- EUI库 - 9 - 数据集合 - 数据容器
DataGroup 设置一个数据源 自动创建内部所需的对象 来完成数据展示 还要设置单条数据的模板 叫ItemRenderer 继承关系 eui.List eui.ListBase e ...
- 19 — node 模块化 及 CommonJS规范 — CommonJS 的由来及各组织与 JS 的关系
ECMAScript 对于不同的环境(运行平台),设计结构,理念,使用方式大相径庭. 1,浏览器 :DOM BOM 2,NodeJS :FS,HTTP 内置模块 : 第三方模块 : 内置模块 3, ...