给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int N=40;
vector<int>ans;
// a:中序遍历 b:前序遍历
int a[N],b[N];
//叶节点的两个空子节点(idx=0)也会入队
//所以数组模拟的队列要开大些
int q[N*N];
int idx;
int n;
struct Node {
int l,r;
} nodes[N];
int build(int L,int R) {
if(L>R)return 0;
int root=++idx;//新的根 从1开始
int mid;//mid是idx编号
//在中序遍历中寻找与当前子树根节点值相同的节点编号
//进行"分左右"的操作
// 前序遍历得根节点,中序遍历划分左右子树
for(mid=L; mid<=R; mid++)if(a[mid]==b[root])break;
nodes[root].l=build(L,mid-1);
nodes[root].r=build(mid+1,R);
return root;
}
void bfs(int s) {
int hh=0,tt=0;
q[0]=s;
while(hh<=tt) {
int t=q[hh++];
if(t==0)continue;
ans.push_back(t);
// 镜像则 存孩子节点时交换顺序
q[++tt]=nodes[t].r;
q[++tt]=nodes[t].l;
}
}
int main() {
cin>>n;
for(int i=1; i<=n; i++)cin>>a[i]; //中序
for(int i=1; i<=n; i++)cin>>b[i]; //前序
int root=build(1,n);
//for(int i=1;i<=idx;i++)swap(nodes[i].l,nodes[i].r);
bfs(root);
int cnt=0;
int si=ans.size();
// 因为build返回的root值是根据前序数组得来的
// 索引映射元素要到前序数组中去
for(auto it:ans) {
cout<<b[it];
cnt++;
if(cnt<si)cout<<' ';
}
return 0;
}