PAT Advanced 1020 Tree Traversals (25) [⼆叉树的遍历,后序中序转层序]

题目

Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, you are supposed to output the level order 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 (<=30), the total number of nodes in the binary tree. The second line gives the postorder 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 level order traversal sequence of the corresponding binary tree. 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:
7
2 3 1 5 7 6 4 1 2 3 4 5 6 7
Sample Output:
4 1 6 3 5 7 2

题目分析

已知后序序列和中序序列,打印层序序列

解题思路

思路 01

  1. int in[n]记录中序序列,int post[n]记录后序序列
  2. 建树
    2.1 post[n-1]为当前根结点root,在in中序序列中找到当前根结点root的位置i,i左边的元素为root的左子树所有结点,i右边元素为root的右子树所有结点
    2.2 将root左子树所有结点作为后序序列继续查找其root和左右子树节点,将root右子树所有结点作为后序序列继续查找其root和左右子树结点
  3. 层序遍历树

思路 02(最优)

  1. int in[n]记录中序序列,int post[n]记录后序序列,node结构体中增加index属性记录树使用数组存储时的节点下标
  2. 前序遍历(利用中序和后序序列,依次找出根节点和其左右子树节点),设置其index,若某根节点index=i,则其左子节点index=2*i+1,其右子节点index=2*i+2
  3. 排序:根据index升序对所有结点排序
  4. 打印排序后的所有结点

思路 03

思路02中的index换为记录层号,对层号进行排序
注:不能使用sort,因为sort不稳定,导致同层顺序得不到保证,需要使用stable_sort()

知识点

  1. 已知中序序列和前序、后序、层序中任意一个序列,可唯一确定一棵二叉树
  2. 后序序列最后一个节点为根节点,该根节点将中序序列一分为二,左边为根节点左子树,右边为根节点右子树
  3. 树的层序遍历(借助队列)
  4. 根据后序序列和中序序列建树
  5. bfs层级遍历时,可以使用数组存储树的特点(即节点存储在下标i,则其左子节点下标为2i+1,右子节点下标为2i+2),之后对下标进行升序排序,遍历即为层序序列;

Code

Code 01

#include <iostream>
#include <queue>
using namespace std;
const int maxn=30;
int pre[maxn],in[maxn],post[maxn];
int n; // the number of nodes
struct node {
	int data;
	node* left;
	node* right;
};
/*
 后序序列和中序序列建树 
*/ 
node * create(int postL,int postR,int inL,int inR) {
	if(postL>postR)return NULL;
	node * root=new node;
	root->data=post[postR];
	// 找到当前根节点在中序遍历中的位置
	int i;
	for(i=inL; i<=inR; i++) {
		if(post[postR]==in[i])
			break;
	}
	int numLeft=i-inL;
	root->left=create(postL,postL+numLeft-1,inL,inL+numLeft-1);//inL+numLeft=i
	root->right=create(postL+numLeft,postR-1,inL+numLeft+1,inR);//inL+numLeft=i
	return root;
}
/*
 树层序遍历
*/
int num=0;
void BFS(node * root) {
	queue<node*> q;
	q.push(root);
	while(!q.empty()) {
		node * now = q.front();
		q.pop();
		printf("%d",now->data);
		num++;
		if(num<n)printf(" ");
		if(now->left!=NULL)q.push(now->left);
		if(now->right!=NULL)q.push(now->right);
	}
}
int main(int argc,char * argv[]) {
	scanf("%d",&n);
	for(int i=0; i<n; i++)
		scanf("%d",&post[i]);
	for(int i=0; i<n; i++)
		scanf("%d",&in[i]);
	node* root=create(0,n-1,0,n-1);
	BFS(root);
	return 0;
}

Code 02(最优)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=30;
int n,in[maxn],post[maxn];
struct node {
	int data;
	int index;
};
vector<node> vns;
bool cmp(node &n1,node &n2){
	return n1.index<n2.index;
}
void pre(int root,int start,int end,int index) {
	if(start>end)return;
	vns.push_back({post[root],index});
	int i;
	while(i<end&&in[i]!=post[root])i++;
	pre(root-(end-i)-1,start,i-1,2*index+1);
	pre(root-1,i+1,end,2*index+2);
}
int main(int argc,char *argv[]) {
	scanf("%d",&n);
	for(int i=0; i<n; i++)
		scanf("%d",&post[i]);
	for(int i=0; i<n; i++)
		scanf("%d",&in[i]);
	pre(n-1,0,n-1,0);
	sort(vns.begin(),vns.end(),cmp);
	for(int i=0;i<vns.size();i++){
		if(i!=0)printf(" ");
		printf("%d",vns[i].data);
	}
	return 0;
}

Code 03

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=30;
int n,in[maxn],post[maxn];
struct node{
	int d;
	int l;
};
vector<node> pre;
void t_pre(int pl,int pr,int il,int ir,int level){
	if(il>ir)return;
	pre.push_back({post[pr],level});
	int k=il;
	while(k<n&&in[k]!=post[pr])k++;
	t_pre(pl,pl+k-il-1,il,k-1,level+1);
	t_pre(pl+k-il,pr-1,k+1,ir,level+1);
}
bool cmp(const node &a,const node &b){
	return a.l<b.l; 
}
int main(int argc,char * argv[]) {
	scanf("%d",&n);
	for(int i=0; i<n; i++)
		scanf("%d",&post[i]);
	for(int i=0; i<n; i++)
		scanf("%d",&in[i]);
	t_pre(0,n-1,0,n-1,1);
	stable_sort(pre.begin(),pre.end(),cmp);
	printf("%d",pre[0]);
	for(int i=1;i<n;i++)
		printf(" %d",pre[i].d);
	return 0;
}
原文地址:https://www.cnblogs.com/houzm/p/12314101.html