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遍历这棵树 ...
随机推荐
- DNS and Bind
DNS : 工作在应用层 DNS 作用 : 完成域名到IP的解析过程 FQDN --> IP 例如 : www.ifeng.com --> 123.103.122.24 D ...
- IDEA快速升级模块版本号
使用场景 一个多模块的项目中,在功能用重大更新后,需要升级版本号,如果不使用工具,需要手动更改每个pom.xml文件,而使用工具,就可以非常快速的完成版本号的更改. 基本步骤 0. idea执行ma ...
- scanf与正则表达式的搭配及应用
scanf与正则表达式的搭配及应用 正则其实我也学的不咋地,只会一点皮毛,正则最大的作用就是当输入流是一个字符串,我们能在输入的时候就滤掉无用信息,省去后期提取数值的步骤. 正则的语法我怕误人子弟,嘿 ...
- POJ 1472:Instant Complexity 模拟时间复杂度
Instant Complexity Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1908 Accepted: 658 ...
- s5pc100开发板网卡驱动的移植
相关软件下载地址:http://pan.baidu.com/s/16yo8Y fsc100开发板 交叉编译工具:arm-cortex_a8-linux-gnueabi-gcc 平台代码修改 vim ...
- Spring Boot2(003):简要回顾“HelloWorld” web 工程
1.注解: @RestController 和 @RequestMapping HelloWorldExample 中的第1个注解 @RestController 是一个被熟知的原型注解(stereo ...
- LCT(2)
LCT(2) 关于 LCT 的基本操作和代码实现见 (1) . 5. LCT的应用 5.0 LCT 裸题 就是LCT的基本操作模板题,常出现于早年省选.不讨论. 5.1 LCT维护子树信息 很多时候, ...
- 错误:selenium.common.exceptions.SessionNotCreatedException: Message: Unable to find a matching set of capabilities
错误再现 原因:firefox浏览器版本和浏览器驱动版本不匹配 解决办法:卸载高版本浏览器,安装低版本浏览器
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-flag
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- Python MySQL Where
章节 Python MySQL 入门 Python MySQL 创建数据库 Python MySQL 创建表 Python MySQL 插入表 Python MySQL Select Python M ...