pat1020
1.题目大意
给定中序和后序遍历,让你重建二叉树。并且输出层序遍历
2.思路
这题使用左右数组来记录左右子孩子的下标,然后,使用queue来进行层序输出。
建树过程如下,首先找到根节点,根节点就在后续遍历的最后一个,接着,中序遍历的两个就是左右子树,然后递归进行建树。
note:同时可以使用map来进行加快索引,既可以记录这个值所在的下标
int build(int il,int ir,int pl,int pr){
// 建树
int root =post[pr];
int k = pos[root];
// 加快索引
if(il<k){
l[root]=build(il,k-1,pl,pl+(k - 1 - il));
}
if(k<ir){
r[root]= build(k + 1, ir, pl + (k - 1 - il) + 1, pr - 1);
}
return root;
}
接下来就是层序遍历,首先push’第一个根节点,然后记录下所有的子节点push进去,直到队列为空
void bfs(int root){
q.push(root);
while (!q.empty()){
auto p =q.front();
q.pop();
if(p!=root){
cout<<' '<<p;
} else{
cout<<p;
}
if(l.count(p))q.push(l[p]);
if(r.count(p))q.push(r[p]);
}
}
3.代码实现
#include <cstring>
#include <iostream>
#include <algorithm>
#include "unordered_map"
#include "queue"
using namespace std;
const int N = 110;
//使用hash可以加快检索,pos记录下标
//post 和in来
int n;
int post[N],in[N];
unordered_map<int ,int> l,r,pos;
queue<int> q;
int build(int il,int ir,int pl,int pr){
// 建树
int root =post[pr];
int k = pos[root];
// 加快索引
if(il<k){
l[root]=build(il,k-1,pl,pl+(k - 1 - il));
}
if(k<ir){
r[root]= build(k + 1, ir, pl + (k - 1 - il) + 1, pr - 1);
}
return root;
}
void bfs(int root){
q.push(root);
while (!q.empty()){
auto p =q.front();
q.pop();
if(p!=root){
cout<<' '<<p;
} else{
cout<<p;
}
if(l.count(p))q.push(l[p]);
if(r.count(p))q.push(r[p]);
}
}
int main()
{
int n;
cin>>n;
for (int i = 0; i < n; ++i) {
cin>>post[i];
}
for (int i = 0; i < n; ++i) {
cin>>in[i];
pos[in[i]]=i;
}
int root= build(0,n-1,0,n-1);
bfs(root);
return 0;
}