PAT A1020 Tree Traversals (25)(25 分)

本文介绍如何根据二叉树的后序遍历和中序遍历序列,构建并输出该二叉树的层次遍历序列。通过递归地构建每个子树,并使用队列实现层次遍历来完成任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目要求:

         

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

算法思路: 

          这道题要求从后序遍历和中序遍历中得到层次遍历的结果。因此,我们第一步先根据提供的后序遍历和中序遍历的结果来构造一棵树,然后编写他的层次遍历算法。

          这道题的核心在于找到对应的后序遍历段和中序遍历段。接着我们对该对应序列进行分析,我们知道,后序遍历的最后一个节点代表的当前树的根节点。而找到该节点在中序遍历中的位置,在中序遍历节点的左侧和右侧分别得到当前树的左子树和右子树。分析,当前左子树和右子树在后续遍历中的位置,得到新的对应序列,生成新子树。

          代码如下:

node* creat(int postL,int postR,int inL,int inR){
	//如果已经遍历完了,那么返回空树
	if(postL>postR){
		return NULL;
	}
	node* root  = new node;
	root->data = postOrder[postR];
	int i = inL;
	//区分左右子树
	for(; i < inR ; i++){
		if( inOrder[i] == root->data){

			break;
		}
	}
	//如果找到,则该节点左侧为左子树,右侧为右子树 左子树节点为 (i-inL) 个, 右子树节点为 (inR - i)
	//且左子树边界 中序遍历[inL,i-1]; 后续遍历为[postL,i-1]
	//右子树边界为 中序遍历 [i+1,inR] 后序遍历为[i+1,postR-1]

	root->lchild = creat(postL , postL+i-inL-1 , inL , i-1 );
	root->rchild = creat(postL+i-inL , postR-1, i+1, inR);


	return root;
}

         关于层次遍历,我们使用一个队列来完成,每次访问当前节点时,将他的左孩子和右孩子依次入队。当队列不为空时,重复该操作。

//层次遍历
//N为元素的个数,用于控制最后一个空格
void levelOrder(node* root,int N){
	int count=0;
	if(root == NULL || N == 0){
		printf("\n");
		return;
	}
	queue<node*> tree;
	tree.push(root);
	while(!tree.empty()){
		node*  temp = tree.front();
		tree.pop();
		if(count < N-1){
			printf("%d ",temp->data);
			count++;
		}else{
			printf("%d\n",temp->data);
		}
		if(temp->lchild != NULL){
			tree.push(temp->lchild);
		}
		if(temp->rchild != NULL){
			tree.push(temp->rchild);
		}
	}
}

代码展示:

#include <cstdio>
#include <queue>

using namespace std;

struct node{
	int data;
	node* lchild;
	node* rchild;
};

int postOrder[31] = {0};
int inOrder[31] = {0};

node* creat(int postL,int postR,int inL,int inR){
	//如果已经遍历完了,那么返回空树
	if(postL>postR){
		return NULL;
	}
	node* root  = new node;
	root->data = postOrder[postR];
	int i = inL;
	//区分左右子树
	for(; i < inR ; i++){
		if( inOrder[i] == root->data){

			break;
		}
	}
	//如果找到,则该节点左侧为左子树,右侧为右子树 左子树节点为 (i-inL) 个, 右子树节点为 (inR - i)
	//且左子树边界 中序遍历[inL,i-1]; 后续遍历为[postL,i-1]
	//右子树边界为 中序遍历 [i+1,inR] 后序遍历为[i+1,postR-1]

	root->lchild = creat(postL , postL+i-inL-1 , inL , i-1 );
	root->rchild = creat(postL+i-inL , postR-1, i+1, inR);


	return root;
}
//层次遍历
//N为元素的个数,用于控制最后一个空格
void levelOrder(node* root,int N){
	int count=0;
	if(root == NULL || N == 0){
		printf("\n");
		return;
	}
	queue<node*> tree;
	tree.push(root);
	while(!tree.empty()){
		node*  temp = tree.front();
		tree.pop();
		if(count < N-1){
			printf("%d ",temp->data);
			count++;
		}else{
			printf("%d\n",temp->data);
		}
		if(temp->lchild != NULL){
			tree.push(temp->lchild);
		}
		if(temp->rchild != NULL){
			tree.push(temp->rchild);
		}
	}
}

int main(){
	int N;
	scanf("%d",&N);

	//从0开始存储,到n-1
	//读入后序遍历序列
	for(int i = 0;i<N;i++){
		scanf("%d",&postOrder[i]);
	}
	//读入中序遍历序列
	for(int i = 0;i<N;i++){
		scanf("%d",&inOrder[i]);
	}
	node* root; 
	root = creat(0,N-1,0,N-1);
	levelOrder(root,N);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值