1138 Postorder Traversal (25 point(s))

本文介绍了一种根据前序遍历和中序遍历序列构造二叉树,并输出后序遍历序列首元素的方法。通过递归创建树结构,实现对二叉树的后序遍历。

1138 Postorder Traversal (25 point(s))

Suppose that all the keys in a binary tree are distinct positive integers. Given the preorder and inorder traversal sequences, you are supposed to output the first number of the postorder 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 (≤ 50,000), the total number of nodes in the binary tree. The second line gives the preorder 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 first number of the postorder traversal sequence of the corresponding binary tree.

Sample Input:

7
1 2 3 4 5 6 7
2 3 1 5 4 7 6

Sample Output:

3

根据前序遍历和中序遍历给出后序遍历。

注意点:

1. C++11引入nullptr作为空指针。C++11以下支持NULL(视为0)。尽量使用nullptr。

2. createTree()的本质是根据前序遍历中root位置是根,而中序遍历是按照左子树、根、右子树的顺序。首先动态建立新的结点,然后新结点的左子树可以根据中序遍历的左边建立,右子树可以根据中序遍历的右边建立,只需要确定在中序遍历中根的位置即可。

3. createTree()注意终止条件(即某子树不存在,left>right,返回空指针nullptr)。

4. 注意返回当前根节点。

#include<iostream>
#include<vector> 
#include<cstring>
using namespace std;
const int MAX = 5e4+7;
struct Node{
	int data;Node* left;Node* right;
	Node(int d):data(d),left(nullptr),right(nullptr){}
};
int pre[MAX],in[MAX];
Node* createTree(int root,int left,int right){
	//前序遍历的root位置是根节点,根据中序的left到right区分左右子树
	if(left>right) return nullptr;
	Node* p = new Node(pre[root]);
	int index = left;
	while(in[index]!=pre[root]) index++;
	p->left = createTree(root+1,left,index-1);
	p->right = createTree(root+index-left+1,index+1,right);
	return p;
}
vector<int> v;
void postOrder(Node* root){
	if(root->left!=nullptr) postOrder(root->left);
	if(root->right!=nullptr) postOrder(root->right);
	v.push_back(root->data);
}
int N;
int main(void){
	cin>>N;
	for(int i=0;i<N;i++) cin>>pre[i];
	for(int i=0;i<N;i++) cin>>in[i];
	Node *root = nullptr;
	root = createTree(0,0,N-1);
	postOrder(root);
	cout<<v[0]<<endl;
	return 0;
}

 

Toggle Sidebar 编程题 6 7-6 红豆生南国 7-6 红豆生南国 分数 25 作者 周强 单位 青岛大学 有诗云: 相思 (王维 唐) 红豆生南国, 春来发几枝。 愿君多采撷, 此物最相思。 那么,我们来采红豆吧! 假设红豆树是这个样子的: 二叉树.png 这种红豆树的特点是: 每个结点都有一个正整数编号,标在结点内部。结点的编号各不相同。 最上方一层结点是 “红豆”(图中红圈所示的5个结点),这一层被称之为红豆层。 树的根结点、左子结点、右子结点、左子树、右子树等的定义与“数据结构”中的“二叉树”相同,但它毕竟是“自然界中的树”,树根在最下方,如图中的结点5 图中这棵红豆树是“完全二叉红豆树”,类似“数据结构”中的“完全二叉树”。(“完全二叉树”的定义:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是完美二叉树。对于一个有N个结点的二叉树,若其结点对应于相同深度完美二叉树的层序遍历的前 N 个结点,这样的树就是完全二叉树) 从图上看,就是:要么每一层(包括红豆层)的结点数达到最大值,要么只在红豆层的最右边缺少一些结点。 对于红豆树,我们定义两种遍历顺序: 正序遍历:先访问树根结点,再正序遍历其左子树,最后正序遍历其右子树 逆序遍历:先逆序遍历其右子树,再逆序遍历其左子树,最后访问树根结点 对于给定的一棵完全二叉红豆树以及一些要采撷的结点,计算每次采撷能采到的红豆数量。 注意:我们采的点,可能是红豆,也可能不是红豆。采撷一个结点的意思是,把这个结点及这个结点的子树的全部结点从树中采下来。 例如:若采结点7,这是红豆结点,我们将获得1颗红豆;若采结点11,这不是红豆结点(而是一个枝结点!),我们将获得红豆树的一枝,包含2个红豆结点(8和2)。 输入格式: 输入有四行。 第一行是一个不超过60的正整数N,表示完全二叉红豆树中的结点数量。 第二行是N个不超过1000的结点编号序列,以空格间隔,表示的是这棵树的逆序遍历序列。 第三行是一个不超过N的正整数K,表示进行K次采撷。 第四行是K个正整数,依次表示每次要采的结点编号。 输出格式: 输出包含K+1行, 前K行,对于输入的每个采撷的点,在一行输出相应获得的红豆数量。如果这个点已经被采掉了,则输出Zao Jiu Cai Diao Le!。如果这个点在原树中根本不存在,则输出Kan Qing Chu Le?。 最后一行,输出采撷结束之后,这棵红豆树的正序遍历序列,用空格分隔,最后一个结点之后没有空格。如果采撷结束之后树已空,则输出Kong Le! 输入样例1: 对于题目中给出的图,对应的输入是: 12 10 4 3 12 6 7 1 2 8 11 9 5 4 15 12 11 2 输出样例1: Kan Qing Chu Le? 1 2 Zao Jiu Cai Diao Le! 5 9 1 7 6 输入样例2: 对于题目中给出的图,对应的输入是: 12 10 4 3 12 6 7 1 2 8 11 9 5 1 5 输出样例2: 5 Kong Le! 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB 栈限制 8192 KB
最新发布
11-13
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值