1127 ZigZagging on a Tree (将层序遍历按z型输出, 2种方法,1.下标法构建满足题意的层序条件 2.构建树 BFS遍历层序)_zigzag_indices-程序员宅基地

技术标签: pat甲级(树类型题)  

1127 ZigZagging on a Tree (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. And it is a simple standard routine to print the numbers in level-order. However, if you think the problem is too simple, then you are too naive. This time you are supposed to print the numbers in "zigzagging order" -- that is, starting from the root, print the numbers level-by-level, alternating between left to right and right to left. For example, for the following tree you must output: 1 11 5 8 17 12 20 15.

zigzag.jpg

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 inorder 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, print the zigzagging sequence of the tree in a line. 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:

8
12 11 20 17 1 15 8 5
12 20 17 11 15 8 5 1

Sample Output:

1 11 5 8 17 12 20 15

/**
本题题意:
给出一颗树的后序,中序遍历(可以推导出先序遍历构建出唯一树),
输出此唯一树的层序遍历不过是z字型输出, eg: 第一层 从右往 左输出,第二层从左往右输出
方法一:本题思路
利用结点下标索引进行排序,先将高度排序,(根节点位于第0层)偶数层从右往左(从大到小排序,) 奇数层从左往右(从小到大排序)
**/

/**
本题题意:
给出一颗树的后序,中序遍历(可以推导出先序遍历构建出唯一树), 
输出此唯一树的层序遍历不过是z字型输出, eg: 第一层 从右往 左输出,第二层从左往右输出 
本题思路 
利用结点下标索引进行排序,先将高度排序,(根节点位于第0层)偶数层从右往左(从大到小排序,) 奇数层从左往右(从小到大排序) 
**/ 
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct Node{
	int h, index, data;	   // 
};
int n;
vector<int> post, in;
vector<Node> zlevel;
bool cmp(Node a, Node b){
	if(a.h != b.h)
		return a.h < b.h;
	else if(a.h % 2 == 0){ //当高度一致时,偶数层从右往左 (索引从大到小输出) 
		return a.index > b.index;
	}else{                 //奇数层,从左往右,(索引从 小 到 大 输出) 
		return a.index < b.index;
	}
}
void preOrder(int postright, int inleft, int inright,int index, int h){
	if(inleft > inright) return;
	int i = inleft;
	while(post[postright] != in[i]) i++;
//	Node node = Node();//注意此步是 Node 没有new  
//	node.data = post[postright];
//	node.h = h;
//	node.index = index;
	zlevel.push_back({h, index, post[postright]});
	preOrder(postright - (inright - i) -1, inleft, i - 1, index * 2 + 1, h + 1);
	preOrder(postright - 1, i + 1, inright, index * 2 + 2, h + 1);
}
int main(){
	scanf("%d", &n);
	in.resize(n); 
	post.resize(n);
	for(int i = 0; i < n; i++){
		scanf("%d", &in[i]); 
	}
	for(int i = 0; i < n; i++){
		scanf("%d", &post[i]);
	}
	preOrder(n - 1, 0, n - 1, 0, 0);
	sort(zlevel.begin(), zlevel.end(), cmp);
	for(int i = 0; i < n; i++){
		if(i != 0) 
			printf(" ");
		printf("%d", zlevel[i].data);
	}
	return 0;
} 

 

方法二:

           根据中序后序推出前序遍历通过链表建立树通过BFS 得到层次遍历,将结点按高度存放在result二维数组中

偶数高度 逆序输出 (从右向左)

奇数高度 正序输出(从左至右)

具体代码:

/**
思路 : 建立一颗树 将每层的结点通过BFS层序遍历分别放入二维向量数组 result[i]中(存放了在高度为i的全部结点) 
	   当高度为偶数时输出 倒序输出 
	   当高度为奇数时输出 正序输出   
**/
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
struct Node{
	Node *l, *r;
	int data, h;
};
int n, cnt = 0; //cnt用来保证最后输出的格式 
vector<int> post, in, result[35]; // 

queue<Node *> q;
Node *preOrder(Node *root, int postright, int inleft, int inright, int h){
	if(inleft > inright){
		return nullptr;
	}
	int i = inleft;
	while(post[postright] != in[i]) i++;
	root = new Node();
	root -> data = post[postright];
	root -> h    = h;
	root -> l = preOrder(root -> l, postright -(inright - i) - 1, inleft, i - 1, h + 1);
	root -> r = preOrder(root -> r, postright - 1, i + 1, inright, h + 1);
	return root;
}

void levelOrder(Node *root){
	q.push(root);
	while(!q.empty()){
		Node *n = q.front();
		q.pop();
	 	result[n->h].push_back(n->data);
		if(n->l != nullptr) 
			q.push(n->l);
		if(n->r != nullptr)
			q.push(n->r);
		}
} 

int main(){
    //k % 2 == 0表示从左至右遍历 k % 2 == 1 表示从右至左遍历 
	Node *root = nullptr;
	scanf("%d", &n);
	in.resize(n);
	post.resize(n);
	for(int i = 0; i < n; i++){
		scanf("%d", &in[i]);
	}
	for(int i = 0; i < n; i++){
		scanf("%d", &post[i]);
	}
	root = preOrder(root, n - 1, 0, n - 1, 0);	 //构建出一棵树 
	levelOrder(root); //进行层序遍历并就结点放入二维向量数组中 
	printf("%d", result[0][0]);
	for(int i = 1; i < n; i++){
		if(i % 2 == 1)
			for(int j = 0; j < result[i].size(); j++)
	            printf(" %d", result[i][j]);			
		if(i % 2 == 0)
			for(int j = result[i].size() - 1; j >= 0; j--)
				printf(" %d", result[i][j]);
	}
	return 0;
}

当然也可以不用链表 静态用数组表示树:

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
struct Node{
	int lindex, rindex, h, index;
}node[35];
int n;
queue<Node> q; 
vector<int> in, post, result[35];
int preOrder(int postright, int inleft, int inright, int h){
	if(inleft > inright) return -1;
	int i = inleft;
	while(post[postright] != in[i]) i++;
	node[postright].index = postright;
	node[postright].h = h;
	node[postright].lindex = preOrder(postright - (inright - i) - 1, inleft, i - 1, h + 1);
	node[postright].rindex = preOrder(postright - 1, i + 1, inright, h + 1);
	return postright;
}

void levelBFS(int postright){
	q.push(node[postright]);
	while(!q.empty()){
		Node n = q.front();
		result[n.h].push_back(post[n.index]);
		q.pop();
		if(n.lindex != -1){
			q.push(node[n.lindex]);
		}
		if(n.rindex != -1){
			q.push(node[n.rindex]);
		}
	}
	
}
int main(){
	int n;
	scanf("%d", &n);
	in.resize(n);
	post.resize(n);
	for(int i = 0; i < n; i++){
		scanf("%d", &in[i]);
	}
	for(int i = 0; i < n; i++){
		scanf("%d", &post[i]);
	}
	preOrder(n - 1, 0, n - 1, 0);
	levelBFS(n - 1);
	printf("%d", result[0][0]);
	for(int i = 1; i < n; i++){
		if(i % 2 == 1)
			for(int j = 0; j < result[i].size(); j++)
	            printf(" %d", result[i][j]);			
		if(i % 2 == 0)
			for(int j = result[i].size() - 1; j >= 0; j--)
				printf(" %d", result[i][j]);
	} 
	return 0;
}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41698081/article/details/91633108

智能推荐

使用nginx解决浏览器跨域问题_nginx不停的xhr-程序员宅基地

文章浏览阅读1k次。通过使用ajax方法跨域请求是浏览器所不允许的,浏览器出于安全考虑是禁止的。警告信息如下:不过jQuery对跨域问题也有解决方案,使用jsonp的方式解决,方法如下:$.ajax({ async:false, url: 'http://www.mysite.com/demo.do', // 跨域URL ty..._nginx不停的xhr

在 Oracle 中配置 extproc 以访问 ST_Geometry-程序员宅基地

文章浏览阅读2k次。关于在 Oracle 中配置 extproc 以访问 ST_Geometry,也就是我们所说的 使用空间SQL 的方法,官方文档链接如下。http://desktop.arcgis.com/zh-cn/arcmap/latest/manage-data/gdbs-in-oracle/configure-oracle-extproc.htm其实简单总结一下,主要就分为以下几个步骤。..._extproc

Linux C++ gbk转为utf-8_linux c++ gbk->utf8-程序员宅基地

文章浏览阅读1.5w次。linux下没有上面的两个函数,需要使用函数 mbstowcs和wcstombsmbstowcs将多字节编码转换为宽字节编码wcstombs将宽字节编码转换为多字节编码这两个函数,转换过程中受到系统编码类型的影响,需要通过设置来设定转换前和转换后的编码类型。通过函数setlocale进行系统编码的设置。linux下输入命名locale -a查看系统支持的编码_linux c++ gbk->utf8

IMP-00009: 导出文件异常结束-程序员宅基地

文章浏览阅读750次。今天准备从生产库向测试库进行数据导入,结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误,google一下,发现可能有如下原因导致imp的数据太大,没有写buffer和commit两个数据库字符集不同从低版本exp的dmp文件,向高版本imp导出的dmp文件出错传输dmp文件时,文件损坏解决办法:imp时指定..._imp-00009导出文件异常结束

python程序员需要深入掌握的技能_Python用数据说明程序员需要掌握的技能-程序员宅基地

文章浏览阅读143次。当下是一个大数据的时代,各个行业都离不开数据的支持。因此,网络爬虫就应运而生。网络爬虫当下最为火热的是Python,Python开发爬虫相对简单,而且功能库相当完善,力压众多开发语言。本次教程我们爬取前程无忧的招聘信息来分析Python程序员需要掌握那些编程技术。首先在谷歌浏览器打开前程无忧的首页,按F12打开浏览器的开发者工具。浏览器开发者工具是用于捕捉网站的请求信息,通过分析请求信息可以了解请..._初级python程序员能力要求

Spring @Service生成bean名称的规则(当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致)_@service beanname-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏6次。@Service标注的bean,类名:ABDemoService查看源码后发现,原来是经过一个特殊处理:当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String C..._@service beanname

随便推点

二叉树的各种创建方法_二叉树的建立-程序员宅基地

文章浏览阅读6.9w次,点赞73次,收藏463次。1.前序创建#include&lt;stdio.h&gt;#include&lt;string.h&gt;#include&lt;stdlib.h&gt;#include&lt;malloc.h&gt;#include&lt;iostream&gt;#include&lt;stack&gt;#include&lt;queue&gt;using namespace std;typed_二叉树的建立

解决asp.net导出excel时中文文件名乱码_asp.net utf8 导出中文字符乱码-程序员宅基地

文章浏览阅读7.1k次。在Asp.net上使用Excel导出功能,如果文件名出现中文,便会以乱码视之。 解决方法: fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);_asp.net utf8 导出中文字符乱码

笔记-编译原理-实验一-词法分析器设计_对pl/0作以下修改扩充。增加单词-程序员宅基地

文章浏览阅读2.1k次,点赞4次,收藏23次。第一次实验 词法分析实验报告设计思想词法分析的主要任务是根据文法的词汇表以及对应约定的编码进行一定的识别,找出文件中所有的合法的单词,并给出一定的信息作为最后的结果,用于后续语法分析程序的使用;本实验针对 PL/0 语言 的文法、词汇表编写一个词法分析程序,对于每个单词根据词汇表输出: (单词种类, 单词的值) 二元对。词汇表:种别编码单词符号助记符0beginb..._对pl/0作以下修改扩充。增加单词

android adb shell 权限,android adb shell权限被拒绝-程序员宅基地

文章浏览阅读773次。我在使用adb.exe时遇到了麻烦.我想使用与bash相同的adb.exe shell提示符,所以我决定更改默认的bash二进制文件(当然二进制文件是交叉编译的,一切都很完美)更改bash二进制文件遵循以下顺序> adb remount> adb push bash / system / bin /> adb shell> cd / system / bin> chm..._adb shell mv 权限

投影仪-相机标定_相机-投影仪标定-程序员宅基地

文章浏览阅读6.8k次,点赞12次,收藏125次。1. 单目相机标定引言相机标定已经研究多年,标定的算法可以分为基于摄影测量的标定和自标定。其中,应用最为广泛的还是张正友标定法。这是一种简单灵活、高鲁棒性、低成本的相机标定算法。仅需要一台相机和一块平面标定板构建相机标定系统,在标定过程中,相机拍摄多个角度下(至少两个角度,推荐10~20个角度)的标定板图像(相机和标定板都可以移动),即可对相机的内外参数进行标定。下面介绍张氏标定法(以下也这么称呼)的原理。原理相机模型和单应矩阵相机标定,就是对相机的内外参数进行计算的过程,从而得到物体到图像的投影_相机-投影仪标定

Wayland架构、渲染、硬件支持-程序员宅基地

文章浏览阅读2.2k次。文章目录Wayland 架构Wayland 渲染Wayland的 硬件支持简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为Wayland Architecture .Wayland 架构若是想要更好的理解 Wayland 架构及其与 X (X11 or X Window System) 结构;一种很好的方法是将事件从输入设备就开始跟踪, 查看期间所有的屏幕上出现的变化。这就是我们现在对 X 的理解。 内核是从一个输入设备中获取一个事件,并通过 evdev 输入_wayland

推荐文章

热门文章

相关标签