PAT 甲级 A1020 Tree Traversals(25 分) 给出中序后续建立原树并层次序遍历

题目在这里:我是题目

今天好好反思,第24行的return root没写卡了我好几个小时。今天一天就弄懂了这一个题,来来反反写了十多次,昨晚是create函数没弄懂,22,23行卡了好久没明白是咋写的(中序前序建原树,本质上一模一样)。如果不会给出中序后序建立原树的读者可以点一下链接,这里不再赘述。

这道题的本质就是考两个点

  1. 给出中序后序数组建立原树
  2. 二叉树层次序遍历

1不懂的读者戳上面的链接,这里详细讲一下2:
二叉树的层次序遍历:
样例树:
在这里插入图片描述
层次序遍历也就是从第一层开始,从左到右读取。层次序读取样例树结果为ABCDEF。
因此用BFS算法是特别适合来解决这个问题的。我们一般也喜欢用queue来实现BFS算法。基本思路如下:

  1. 将根结点root加入队列q。
  2. 取出队首结点,访问他。
  3. 如果该结点有左孩子,将左孩子加入队。
  4. 如果该结点有右孩子,将右孩子加入队。
  5. 返回2,直到队列为空。

于是可以根据这个思路写出具体代码。

//层次序遍历
void LayerOrder(node* root){
   queue<node*>q; //注意队列里是存地址
   q.push(root);	//将根结点地址入队
   while(!q.empty()){
   node* now = root;	//取出队首元素暂存起来
   q.pop();
   printf("%d",now->data); 	//访问队首元素
   if(now->lchild!=NULL) q.push(now->lchild);
   if(now->rchild!=NULL) q.push(now->rchild);
   }
}

这串代码是BFS层次访问二叉树的模板代码,但是具体的变量名以及作用(printf())里面的东西根据自己的需要修改,此处默认树的元素是int。

根据1和2组装起来这个题目就完美啦。
注意点:

  1. 输出的最后不能带空格,需要处理
  2. create函数里面的小细节不能错,调起来挺麻烦的

AC代码:

#include <bits/stdc++.h>
using namespace std;
struct node{
	int data;
	node* lchild;
	node* rchild;
};
const int maxn = 50;
int n,pre[maxn],in[maxn],post[maxn];

node* create(int postL,int postR,int inL,int inR){
	if(postL>postR) return NULL;
	node* root = new node;
	root->data = post[postR];
	int k;
	for(k=inL;k<=inR;k++){
		if(in[k]==post[postR])
			break;//易错点(写成return NULL)
	}
	int numLeft = k - inL;
	root->lchild = create(postL,postL+numLeft-1,inL,k-1);
	root->rchild = create(postL+numLeft,postR-1,k+1,inR);
	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->lchild!=NULL) q.push(now->lchild);
		if(now->rchild!=NULL) q.push(now->rchild);
	}
}
int main(){
	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]);
	}
	BFS(create(0,n-1,0,n-1));
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值