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

news2024/12/23 3:17:45

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;
} 

运行结果:

两种情况均可通过测试点

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【十年java搬砖路】Jumpserver docker版安装及配置Ldap登陆认证

Jumpserver docker 安装启动教程 拉取镜像 docker pull JumpServer启动进行前确保有Redis 和Mysql 创建jumperServer数据库 在MYSQL上执行 创建数据库 登陆MYSQL mysql -u root -p 创建Jumperserveri库 create database jumpserver default charset utf8mb4;可以为jumperSe…

视频监控汇聚EasyCVR助力山体滑坡/自然灾害可视化监测与应急救援

近日&#xff0c;巴布亚新几内亚恩加省遭遇山体滑坡&#xff0c;持续引发关注。截至5月29日&#xff0c;恩加省山体滑坡导致的遇难人数可能超过2000人。据悉&#xff0c;巴布亚新几内亚恩加省位于巴布亚新几内亚中部高原的西部&#xff0c;地形多山。由于事发地区相对偏远&…

自定义数据库连接池

为什么要用数据库连接池&#xff1f; mysql连接资源非常宝贵&#xff0c;创建连接和关闭连接花费的时间比较长&#xff0c;使用数据库连接池可以提高我们开发效率&#xff0c;用户从连接池获取连接使用用完了后&#xff0c;需要把连接归还给连接池&#xff0c;所以我们需要用L…

Rasa.3X中使用lookup实现对实体的抽取

rasa3.6的DIETClassifier实体提取器不准确&#xff0c;使用RegexEntityExtractor的实体提取器替换。在实战过程解决以下两个问题&#xff1a; 1、RegexEntityExtractor实体提取器的应用 首先在domain.yml中明确对应的实体以及意图&#xff1a; version: "3.0" ent…

【知识拓展】机器学习基础(二):什么是模型、自定义模型、模型训练、模型调优

前言 接上文&#xff0c;前文对模型没有过多介绍&#xff0c;随着看的资料增多&#xff0c;对模型有了更多的自我认识&#xff0c;记录一下。要了解模型&#xff0c;我们先从零开始创建一个模型开始&#xff1a; 最简单的方法是使用Python和scikit-learn库。关于scikit-learn库…

iframe内嵌网页自适应缩放 以展示源网页的比例尺寸

需求:这是我最近开发的低代码平台遇到的需求 ,要求将配置好的应用在弹框中预览(将预览网页内嵌入弹框中) 但是内嵌进入后 他会截取一部分(我源网站网页尺寸 是1980x1080 或者 3060X2160等等) 但是我这个dialog弹框只有我自定义的1000多px的宽高 他只会展示我iframe网页的一部分…

Docker安装Zookeeper(单机)

Docker安装Zookeeper&#xff08;单机&#xff09; 目录 Docker安装Zookeeper&#xff08;单机&#xff09;拉取镜像创建目录添加配置文件启动容器测试 拉取镜像 docker pull zookeeper创建目录 mkdir -p /data/zookeeper/data # 数据挂载目录 mkdir -p /data/zookeeper/conf…

身份认证与口令攻击

身份认证与口令攻击 身份认证身份认证的五种方式口令认证静态口令动态口令(一次性口令)动态口令分类 密码学认证一次性口令认证S/KEY协议改进的S/KEY协议 其于共享密钥的认证 口令行为规律和口令猜测口令规律口令猜测 口令破解操作系统口令破解Windows密码存储机制Windows密码破…

一步将 CentOS 7.x 原地迁移至 RHEL 7.9

《OpenShift / RHEL / DevSecOps 汇总目录》 在《在离线环境中将 CentOS 7.X 原地迁移至 RHEL 7.9》一文中为了实现从 CentOS 7.X 原地迁移至 RHEL 7.9&#xff0c;我们第一步先将一个测试环境 CentOS 7.5 升级到 CentOS 7.9&#xff0c;然后在第二步使用 convert2rhel &…

太阳能语音警示杆在户外的应用及其作用

一、太阳能语音警示杆的主要应用领域 交通管理&#xff1a;在城市道路、乡村公路、高速公路等交通要道&#xff0c;太阳能语音警示杆可以用于提醒驾驶员注意前方路况、减速慢行或者避让施工区域。例如&#xff0c;在临时施工路段&#xff0c;警示杆可以播放“前方施工&#xf…

HTML语义化标签

<header> 主要用于网页整体顶部&#xff0c;<article>头部&#xff0c;<section>头部 <nav> 导航&#xff0c;一般有主要导航&#xff0c;路径导航&#xff0c;章节导航&#xff0c;内容目录导航 <main> 网页主要区域&#xff0c;一般一个网页…

Mysql基础教程(11):DISTINCT

MySQL DISTINCT 用法和实例 当使用 SELECT 查询数据时&#xff0c;我们可能会得到一些重复的行。比如学生表中有很多重复的年龄。如果想得到一个唯一的、没有重复记录的结果集&#xff0c;就需要用到 DISTINCT 关键字。 MySQL DISTINCT用法 在 SELECT 语句中使用 DISTINCT 关…

STM32高级控制定时器之输入捕获模式

目录 概述 1 输入捕获模式 1.1 原理介绍 1.2 实现步骤 1.3 发生输入捕获流程 2 使用STM32Cube配置工程 2.1 软件环境 2.2 配置参数 2.3 生成项目文件 3 功能实现 3.1 PWM调制占空比函数 3.2 应用函数库 4 测试 4.1 功能框图 4.2 运行结果 源代码下载地址&#xf…

chrome调试手机网页

前期准备 1、 PC端安装好chrmoe浏览器 2、 安卓手机安装好chrmoe浏览器 3、 数据线 原文地址&#xff1a;https://lengmo714.top/343880cb.html 手机打开调试模式 进入手机设置&#xff0c;找到开发者模式&#xff0c;然后启用USB调试 打开PC端chrome调试功能 1、点击chr…

部署专属网页版ChatGPT-Next-Web

背景 工作学习中经常使用chat-gpt, 需求是多端使用gpt问答&#xff0c;因此搭建一个网页版本方便多个平台使用。最后选择了 ChatGPT-Next-Web 部署说明 一键部署自己的web页面&#xff0c;因为是使用免费的vercel托管的&#xff0c;vercel节点在全球都有&#xff0c;理论上突…

OAK相机如何将 YOLOv10 模型转换成 blob 格式?

编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查看首发地址链接。 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是Ashely。 专…

NVIDIA Blackwell Architecture

本文翻译自&#xff1a;NVIDIA Blackwell Architecture https://www.nvidia.com/en-us/data-center/technologies/blackwell-architecture/ 文章目录 了解技术突破1、新型人工智能超级芯片2、第二代 Transformer 引擎3、Secure AI4、NVLink 和 NVLink 交换机5、解压缩引擎6、可…

景源畅信数字:抖音新手如何找好自己的发布领域?

在短视频的浪潮中&#xff0c;抖音以其独特的魅力吸引了众多用户。对于刚踏入这个平台的新手来说&#xff0c;找到适合自己的发布领域至关重要。那么&#xff0c;如何在这个充满竞争的平台上找到自己的定位呢?接下来&#xff0c;就让我们一起来探讨这个问题。 一、明确兴趣爱好…

Java18+ springboot+mysql +Thymeleaf 技术架构开发的全套同城服务家政上门系统源码(APP用户端+APP服务端+PC管理端)

Java springbootmysql Thymeleaf 技术架构开发的全套同城服务家政上门系统源码&#xff08;APP用户端APP服务端PC管理端&#xff09; 家政上门预约系统&#xff1a;该系统综合运用springboot、java1.8、vue移动支付、微信授权登录等技术&#xff0c;由用户小程序、站长小程序、…

AI网络爬虫:无限下拉滚动页面的另类爬取方法

现在很多网页都是无限下拉滚动的。可以拉动到底部&#xff0c;然后保存网页为mhtml格式文件。 接着&#xff0c;在ChatGPT中输入提示词&#xff1a; 你是一个Python编程高手&#xff0c;要完成一个关于爬取网页内容的Python脚本的任务&#xff0c;下面是具体步骤&#xff1a; …