03-树3 Tree Traversals Again(浙大数据结构PTA习题)

03-树3 Tree Traversals Again        分数 25        作者 陈越

An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.


                                                                        Figure 1

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow, each describes a stack operation in the format: "Push X" where X is the index of the node being pushed onto the stack; or "Pop" meaning to pop one node from the stack.

Output Specification:

For each test case, print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:

6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop

Sample Output:

3 4 2 6 5 1

代码长度限制:16 KB        时间限制:400 ms        内存限制:64 MB

题目解析:

本质是根据一棵树的先序遍历结果和中序遍历结果,求解这棵树的后序遍历结果。

在树的遍历中,知中序和先序可求唯一后序;知中序和后序可求唯一先序;知先序和后序不可求唯一中序。

关键点1:根据输入获得先序遍历结果和中序遍历结果

关键点2:根据先序和中序遍历结果输出后序遍历结果

下面将演示建树和不建树两种情况

代码展示:

不建树的情况

// 根据先序遍历与中序遍历求后序遍历

# include<stdio.h>
# include<string.h>
# define MAXSIZE 5

void Solve(int preL, int inL, int postL, int n, int pre[], int in[], int post[]);

int main(){
	// 一共有多少个结点 
	int N;
	scanf("%d",&N);
	// 创建一个堆栈
	int Stack[N];
	int Rear = -1;
	// 分别创建前、中、后序遍历的结果数组
	int Pre[N],In[N],Post[N];
	int PreRear = -1;
	// count作为弹出元素的计数
	int num, count = 0;
	while(count!=N){
		char handle[MAXSIZE];
		scanf("%s",handle);
		if(!strcmp(handle,"Push")){
			// 接受一个数字并压入栈
			scanf("%d",&num);
			Stack[++Rear] = num; 
			// 前序遍历数组记录
			Pre[++PreRear] = num; 
		}else{
			// 出栈并在中序遍历中进行记录 
			num = Stack[Rear--];
			In[count++] = num;
		}
	} 
	
	// 有了前序与中序遍历结果,接下来通过递归函数求后序遍历结果 
	Solve(0,0,0,N,Pre,In,Post);
	int i;
	for(i=0;i<N;i++){
		if(i!=N-1)printf("%d ",Post[i]);
		else printf("%d",Post[i]);
	}
} 

void Solve(int preL, int inL, int postL, int n, int pre[], int in[], int post[]){
	if(n==0)return;
	if(n==1){
		post[postL] = pre[preL];
		return;
	}
	// 先序的第一个放在给定后序的最后一个 
	int root = pre[preL];
	post[postL+n-1] = root;
	// 找出左子树的范围 
	int i;
	for(i=0;i<n;i++){
		if(in[inL+i]==root)break;
	}
	// 左子树要处理的的结点数 
	int L = i;
	// 右子树要处理的结点数 
	int R = n-L-1;
	// 递归处理 
	Solve(preL+1, inL, postL,L,pre,in,post);
	Solve(preL+L+1,inL+L+1,postL+L,R,pre,in,post);
	return; 
}

建树的情况:

# include<stdio.h>
# include<stdlib.h>
# include<string.h>
# define MAXNODE 30
# define MAXLENGTH 5

typedef struct TreeNode* Tree;
struct TreeNode{
	int data;
	Tree left;
	Tree right;
}; 

void PostOrder(Tree root,int data);
void CreateTree(int left1,int right1,int left2,int right2,int Pre[],int In[], Tree root);

int main(){
	// 创建一个堆栈
	int Stack[MAXNODE];
	int SHead = -1; 
	// 接收结点个数 
	int N;
	scanf("%d",&N);
	getchar();
	// 分别创建一个用来记录先序和中序遍历结果的数组
	int PreArray[N],InArray[N];
	int PreHead=-1, InHead=-1;
	// 接收操作输入,因为有出入栈,因此共有2*N次操作 
	int i,num;
	char* str = (char*)malloc(sizeof(char)*MAXLENGTH);
	for(i=0;i<2*N;i++){
		scanf("%s",str);
		if(strcmp(str,"Push")==0){
			// 入栈
			scanf("%d",&num);
			getchar();
			Stack[++SHead] = num;
			// 记录先序
			PreArray[++PreHead] = num; 
		}else{
			// 出栈
			num = Stack[SHead--];
			// 记录中序
			InArray[++InHead] = num; 
		}
	}
	
	// 创建根结点
	Tree root = (Tree)malloc(sizeof(struct TreeNode));
	root->data = PreArray[0];
	root->left = NULL;
	root->right = NULL;
	// 构建树
	CreateTree(0,N-1,0,N-1,PreArray,InArray,root);
	// 后序输出遍历结果,为了格式化输出因此传入根结点的值作为判读依据 
	PostOrder(root,root->data); 
	
	return 0; 
}

// 递归后序遍历树
void PostOrder(Tree root,int data){
	if(root){
		PostOrder(root->left,data);
		PostOrder(root->right,data);
		if(root->data == data)printf("%d",root->data);
		else printf("%d ",root->data);
	}
	return;
} 

// 根据先序和后序构建一棵树;left1与right1表示先序序列的范围;left2与right2表示后序序列的范围
void CreateTree(int left1,int right1,int left2,int right2,int Pre[],int In[], Tree root){
	// 首先找到根结点在中序中的位置
	int i,index;
	for(i=left2;i<=right2;i++){
		if(root->data == In[i]){
			index = i;
			break;
		}
	} 
	// 如果根结点有左孩子 
	if(index!=left2){
		// 创建一个左孩子结点
		Tree left_son = (Tree)malloc(sizeof(struct TreeNode));
		left_son->data = Pre[left1+1];
		left_son->left = NULL;
		left_son->right = NULL;
		root->left = left_son;
		// 递归构建这个左孩子结点
		CreateTree(left1+1,index-left2+left1,left2,index-1,Pre,In,left_son); 
	}
	// 如果根结点有右孩子
	if(index!=right2){
		Tree right_son = (Tree)malloc(sizeof(struct TreeNode));
		right_son->data = Pre[index-left2+left1+1];
		right_son->left = NULL;
		right_son->right = NULL;
		root->right = right_son;
		// 递归构建这个右孩子结点
		CreateTree(index-left2+left1+1,right1,index+1,right2,Pre,In,right_son); 
	} 
	return;
} 

运行结果:

两种情况均可通过测试点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/665577.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

实际测试stm32中断优先级

https://m.weibo.cn/1711020180/5040208380168258

【字典树(前缀树) 哈希映射 后序序列化】1948. 删除系统中的重复文件夹

本文涉及知识点 字典树&#xff08;前缀树) 哈希映射 后序序列化 LeetCode 1948. 删除系统中的重复文件夹 由于一个漏洞&#xff0c;文件系统中存在许多重复文件夹。给你一个二维数组 paths&#xff0c;其中 paths[i] 是一个表示文件系统中第 i 个文件夹的绝对路径的数组。 …

Codeforces Round 949 (Div. 2) (A~C)

1981A - Turtle and Piggy Are Playing a Game 贪心&#xff0c;每次取x 2&#xff0c;求最大分数 // Problem: B. Turtle and an Infinite Sequence // Contest: Codeforces - Codeforces Round 949 (Div. 2) // URL: https://codeforces.com/contest/1981/problem/B // Me…

iOS组件化 方案 实现

iOS组件化 组件化的原因现在流行的组件化方案方案一、url-block &#xff08;基于 URL Router&#xff09;方案二、protocol调用方式解读 方案三、target-action调用方式解读 gitHub代码链接参考 组件化的原因 模块间解耦模块重用提高团队协作开发效率单元测试 当项目App处于…

2024最新群智能优化算法:大甘蔗鼠算法(Greater Cane Rat Algorithm,GCRA)求解23个函数,提供MATLAB代码

一、大甘蔗鼠算法 大甘蔗鼠算法&#xff08;Greater Cane Rat Algorithm&#xff0c;GCRA&#xff09;由Jeffrey O. Agushaka等人于2024年提出&#xff0c;该算法模拟大甘蔗鼠的智能觅食行为。 参考文献 [1]Agushaka J O, Ezugwu A E, Saha A K, et al. Greater Cane Rat Alg…

LAMMPS - 分子动力学模拟器

本文翻译自&#xff1a;https://www.lammps.org/ 文章目录 一、关于 LAMMPS下载作者R&D 100 二、LAMMPS 亮点毛细血管中的血流 一、关于 LAMMPS 官网&#xff1a; https://www.lammps.org/ github &#xff1a;https://github.com/lammps/lammps LAMMPS 分子动力学模拟器…

初识java——javaSE(8)异常

文章目录 一 异常的概念与体系结构1.1 什么是异常&#xff1f;1.2 异常的体系结构&#xff01;1.3 编译时异常与运行时异常与Error编译时异常&#xff1a;异常声明&#xff1a;throws关键字 运行时异常&#xff1a;什么是Error? 二 处理异常2.1 异常的抛出&#xff1a;throw(注…

利用映射算子打印菱形

文章目录 一、利用RDD完成&#xff08;一&#xff09;右半菱形&#xff08;二&#xff09;左半菱形&#xff08;三&#xff09;完整菱形&#xff08;四&#xff09;输出任意大菱形 二、利用Java完成&#xff08;一&#xff09;右半菱形&#xff08;二&#xff09;左半菱形&…

恒压频比开环控制系统Matlab/Simulink仿真分析(SPWM控制方式)

介绍恒压频比的开环控制方法驱动永磁同步电机的转动&#xff0c;首先分析恒压频比的控制原理&#xff0c;然后在Matlab/Simulink中进行永磁同步电机恒压频比开环控制系统的仿真分析&#xff0c;最后将Simulink中的恒压频比控制算法生成代码加载到实际工程中进行工程实现。 一、…

react 表格实现拖拽功能

项目背景 : react ant 单纯实现拖拽确实不难 , 我的需求是根据后台接口返回 , 生成对应的父子表格 , 并只可以拖拽子的位置 , 如图 后台返回的数据结构 (pid为0说明是父 , 子的pid等于父的id , 说明是父的子) 1 , 我先转成了树形结构且自己加上了key (注意 : key一定得是唯一的…

异常(Exception)

捕获异常 public class test {public static void main(String [] args) {int[] arr {1,2,3,4,5};try {System.out.println(arr[10]);}catch (ArrayIndexOutOfBoundsException e) {//索引越界异常System.out.println("索引越界");}System.out.println("看看我是…

测试FaceRecognitionDotNet报错“Error deserializing object of type int”

FaceRecognitionDotNet宣称是最简单的.net人脸识别模块&#xff0c;其内部使用Dlib、DlibDotNet、OpenCVSharp等模块实现人脸识别&#xff0c;网上有不少介绍文章。实际测试过程中&#xff0c;在调用FaceRecognition.Create函数创建FaceRecognition实例对象时&#xff0c;会报如…

AI入门:普通人可以利用AI做什么?休闲时间赚点小钱?(含多种实践案例)

大家好&#xff0c;我是影子&#xff0c;一名AI编程深耕者。 最近&#xff0c;有很多 AI 小白问我&#xff0c;AI到底可以做些什么&#xff1f;对我们普通人能有哪些帮助&#xff1f; 在我看来&#xff0c;对于我们刚接触 AI 的小伙伴而言。我们可以利用 AI 为我们工作提效&…

构建 VPC 并启动 Web 服务器

实验 2&#xff1a;构建 VPC 并启动 Web 服务器 目标 完成本实验后&#xff0c;您可以&#xff1a; 创建 VPC。创建子网。配置安全组。在 VPC 中启动 EC2 实例。任务 1&#xff1a;创建 VPC 在本任务中&#xff0c;您将使用 VPC 向导在单个可用区中创建一个 VPC、一个互联网网关…

神经网络---卷积神经网络CNN

一、从前馈神经网络到CNN 前馈神经网络&#xff08;Feedforward Neural Networks&#xff09;是最基础的神经网络模型&#xff0c;也被称为多层感知机&#xff08;MLP&#xff09;。 它由多个神经元组成&#xff0c;每个神经元与前一层的所有神经元相连&#xff0c;形成一个“…

电子电气SCI期刊,中科院1区TOP,收稿范围广泛

一、期刊名称 IEEE Transactions on Smart Grid 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;工程技术 影响因子&#xff1a;9.6 中科院分区&#xff1a;1区 三、期刊征稿范围 IEEE Transactions on Smart Grid是一本跨学科期刊&#xff0c;旨在传播智…

Gbase 国产数据库

参考&#xff1a;参考&#xff1a; 5分钟学会Linux环境GBase 8t安装和部署 - 光洋山 - twt企业IT交流平台 (talkwithtrend.com)https://www.talkwithtrend.com/Article/197237 视频 GBase 8s快速入门-功能简介与演示-大数据教程-腾讯课堂 (qq.com)https://ke.qq.com/course/…

Qt 插件机制使用及原理

目录 1.引言 2.插件原理 3.插件实现 3.1.定义一个接口集(只有纯虚函数的类) 3.2.实现接口 4.插件的加载 4.1.静态插件 4.1.1.静态插件实现方式 4.1.2.静态插件加载的过程 4.1.3.示例 4.2.动态插件 4.2.1.动态插件的加载过程 5.定位插件 6.插件开发的优势 7.总结…

蓝桥杯高频考点-与日期相关的题目

文章目录 前言1. 如何枚举合法日期1.1 预存每个月的天数1.2 封装一个判断日期是否合法的函数1.3 枚举日期并判断日期是否合法 2. 判断日期是否为回文日期2.1 将日期当作字符串进行处理2.2 将日期当作一个8位数进行处理 3. 给定初始日期&#xff0c;计算经过n天后对应的日期3.1 …

Java集合【超详细】2 -- Map、可变参数、Collections类

文章目录 一、Map集合1.1 Map集合概述和特点【理解】1.2 Map集合的基本功能【应用】1.3 Map集合的获取功能【应用】1.4 Map集合的两种遍历方式 二、HashMap集合2.1 HashMap集合概述和特点【理解】2.2 HashMap的组成、构造函数2.3 put、查找方法2.4 HashMap集合应用案例【应用】…