题目在这里:我是题目
今天好好反思,第24行的return root没写卡了我好几个小时。今天一天就弄懂了这一个题,来来反反写了十多次,昨晚是create函数没弄懂,22,23行卡了好久没明白是咋写的(中序前序建原树,本质上一模一样)。如果不会给出中序后序建立原树的读者可以点一下链接,这里不再赘述。
这道题的本质就是考两个点
- 给出中序后序数组建立原树
- 二叉树层次序遍历
1不懂的读者戳上面的链接,这里详细讲一下2:
二叉树的层次序遍历:
样例树:
层次序遍历也就是从第一层开始,从左到右读取。层次序读取样例树结果为ABCDEF。
因此用BFS算法是特别适合来解决这个问题的。我们一般也喜欢用queue来实现BFS算法。基本思路如下:
- 将根结点root加入队列q。
- 取出队首结点,访问他。
- 如果该结点有左孩子,将左孩子加入队。
- 如果该结点有右孩子,将右孩子加入队。
- 返回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组装起来这个题目就完美啦。
注意点:
- 输出的最后不能带空格,需要处理
- 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));
}