这道题是后序遍历转中序遍历,再输出为层次遍历的题,后序遍历转中序遍历参考了算法笔记的做法,要注意的是,在dfs的过程中,cnt的值是可以改变的,所以要提前记录下来;以及,这道题虽然样例里所有的点都在1到n的范围内,但是实际上,并没有说明这一点,所以要记录下来每一个点的数字。
#include <iostream>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<cstdlib>
#include<queue>
#include<cstring>
#include<set>
#include<list>
using namespace std;
struct Node
{
int l,r,id;
};
Node t[101];
int post[101];
int in[101];
int n;
int cnt=0;
void dfs(int father,bool isLeft,int postL,int postR,int inL,int inR)
{
// if(father==-1) cout<<"father:"<<"无:"<<" postL:"<<postL<<" postR:"<<postR<<" inL:"<<inL<<" inR:"<<inR<<endl;
//else cout<<"father:"<<t[father].id<<" postL:"<<postL<<" postR:"<<postR<<" inL:"<<inL<<" inR:"<<inR<<endl;
if(postL>postR)return;
int root=post[postR];
cnt++;
t[cnt].id=root;
t[cnt].l=-1;
t[cnt].r=-1;
if(father!=-1)
{
if(isLeft)t[father].l=cnt;
else t[father].r=cnt;
}
int inRootPos;
for(int i=inL;i<=inR;i++)
{
if(in[i]==root)
{
inRootPos=i;
break;
}
}
int leftLength=inRootPos-inL;
int rightLength=inR-inRootPos;
int w=cnt;
if(leftLength>0)dfs(w,true,postL,postL+leftLength-1,inL,inRootPos-1);
if(rightLength>0)dfs(w,false,postL+leftLength,postR-1,inRootPos+1,inR);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&post[i]);
for(int i=1;i<=n;i++)
scanf("%d",&in[i]);
dfs(-1,false,1,n,1,n);
// cout<<"cnt:"<<cnt<<endl;
queue<Node>q;
q.push(t[1]);
vector<int>ans;
while(!q.empty())
{
Node head=q.front();
q.pop();
ans.push_back(head.id);
if(head.l!=-1)q.push(t[head.l]);
if(head.r!=-1)q.push(t[head.r]);
}
for(int i=0;i<ans.size()-1;i++)
printf("%d ",ans[i]);
printf("%d",ans[ans.size()-1]);
}