题目大意:给出一个序列的中序和后序,输出该序列的层次遍历序列。
解决方法:重建二叉树+层次遍历
/*根据二叉树的后序和中序,重建二叉树,输出层次序列*/
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstdlib>
using namespace std;
vector<int>in,post;
int pos;
int N;
struct Bitree{
int data;
Bitree *lson;
Bitree *rson;
};
//重建二叉树
Bitree* rec(int l,int r){
if(l>=r)return NULL;
int root=post[pos--];
int m=distance(in.begin(),find(in.begin(),in.end(),root));
Bitree *t;
t=(Bitree *)malloc(sizeof(Bitree));
t->data=root;
t->rson=rec(m+1,r);
t->lson=rec(l,m);
return t;
}
//层次遍历
//由于格式要求,需要先保存结果,而不直接进行输出
void bfs(Bitree *b){
vector<int>res;
queue<Bitree *>q;
q.push(b);
while(!q.empty()){
Bitree* tmp=q.front();
q.pop();
res.push_back(tmp->data);
if(tmp->lson!=NULL){
q.push(tmp->lson);
}
if(tmp->rson!=NULL){
q.push(tmp->rson);
}
}
for(int i=0;i<res.size();i++){
cout<<res[i];
if(i!=res.size()-1)cout<<" ";
}
}
int main(){
cin>>N;
pos=N-1;
for(int i=0;i<N;i++){
int a;
cin>>a;
post.push_back(a);
}
for(int i=0;i<N;i++){
int a;
cin>>a;
in.push_back(a);
}
Bitree *bt;
bt=rec(0,N);
//输出层次遍历
bfs(bt);
return 0;
}
该类相似问题:
1.在该问题的基础上,输出前序序列。这时可以对重建后的二叉树进行先序遍历,便可得到。
2.给出二叉树的先序和中序,给出后序或层次遍历。
/*根据二叉树的先序和中序,重建二叉树,输出后序和层次序列*/
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstdlib>
using namespace std;
vector<int>pre,in,post;
int pos;
int N;
struct Bitree{
int data;
Bitree *lson;
Bitree *rson;
};
Bitree* rec(int l,int r){
if(l>=r)return NULL;
int root=pre[pos++];
int m=distance(in.begin(),find(in.begin(),in.end(),root));
cout<<"m:"<<m<<endl;
Bitree *t;
t=(Bitree *)malloc(sizeof(Bitree));
t->data=root;
t->lson=rec(l,m);
t->rson=rec(m+1,r);
post.push_back(root);
return t;
}
void bfs(Bitree *b){
queue<Bitree *>q;
q.push(b);
while(!q.empty()){
Bitree* tmp=q.front();
q.pop();
cout<<tmp->data<<" ";
if(tmp->lson!=NULL){
q.push(tmp->lson);
}
if(tmp->rson!=NULL){
q.push(tmp->rson);
}
}
}
int main(){
cin>>N;
pos=0;
for(int i=0;i<N;i++){
int a;
cin>>a;
pre.push_back(a);
}
for(int i=0;i<N;i++){
int a;
cin>>a;
in.push_back(a);
}
Bitree *bt;
bt=rec(0,N);
//输出后序
for(int i=0;i<pre.size();i++){
cout<<post[i]<<" ";
}
cout<<endl;
//输出层次遍历
bfs(bt);
return 0;
}
心得:
问题1:给出先序和中序求后序
问题2:给出后序和中序求先序
首先三种序列的顺序为:
先序:根左右
中序:左根右
后序:左右根
两种问题的解决思路的区别:
1.重建二叉树时存在不同
问题1:对先序序列从头开始遍历,并寻找该结点在中序序列中的对应位置,然后重建左子树、右子树。
问题2:对后序序列从尾开始遍历,并并寻找该结点在中序序列中的对应位置,然后重建右子树、左子树。
两者之间的差异是由于先序序列和后序序列的差异。
2.问题1获取结果序列时,可以在重建二叉树的过程中使用vector进行保存,但问题2不可以,因为先重建的右子树。两者都可以先重建二叉树,再进行遍历的方法得到结果序列。