注释版:
#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a);
using namespace std;
typedef long long ll;
const int maxn=50;
int mid[maxn],po[maxn],pr[maxn];
int first;
struct node
{
int l,r;
}T[maxn];
// 中序+先序=>二叉树
int mid_pr_build(int la,int ra,int lb,int rb) // la,ra:表示中序遍历 lb,rb:表示先序遍历
{
if(la>ra) return 0;
int rt=pr[lb]; // 因为先序遍历第一个是根节点
int p1=la,p2;
while(mid[p1]!=rt) p1++; // 在中序遍历中找到根节点
p2=p1-la;
T[rt].l=mid_pr_build(la,p1-1,lb+1,lb+p2); // 左子树(锁定左子树范围的下标)
T[rt].r=mid_pr_build(p1+1,ra,lb+p2+1,rb); // 右子树(锁定右子树范围的下标)
return rt;
}
// 中序+后序=>二叉树
int mid_po_build(int la,int ra,int lb,int rb) // la,ra:表示中序遍历 lb,rb:表示后序遍历
{
if(la>ra) return 0;
int rt=po[rb]; // 因为后序遍历最后一个是根节点
int p1=la,p2;
while(mid[p1]!=rt) p1++; // 在中序遍历中找到根节点
p2=p1-la;
T[rt].l=mid_po_build(la,p1-1,lb,lb+p2-1); // 左子树(锁定左子树范围的下标)
T[rt].r=mid_po_build(p1+1,ra,lb+p2,rb-1); // 右子树(锁定右子树范围的下标)
return rt;
}
// 层序遍历
void bfs(int rt)
{
queue<int> q;
vector<int> v;
q.push(rt);
while(!q.empty())
{
int w=q.front();
q.pop();
v.push_back(w);
if(T[w].l!=0) q.push(T[w].l);
if(T[w].r!=0) q.push(T[w].r);
}
int len=v.size();
for(int i=0;i<len;i++)
printf("%d%c",v[i],i==len-1?'\n':' '); // 推荐这种写法,简洁
}
// 先序遍历
void preT(int rt)
{
if(rt==0) return;
printf(first?first=0,"%d":" %d",rt);
preT(T[rt].l);
preT(T[rt].r);
}
// 中序遍历
void midT(int rt)
{
if(rt==0) return;
midT(T[rt].l);
printf(first?first=0,"%d":" %d",rt);
midT(T[rt].r);
}
// 后序遍历
void postT(int rt)
{
if(rt==0) return;
postT(T[rt].l);
postT(T[rt].r);
printf(first?first=0,"%d":" %d",rt);
}
int main()
{
int n;
while(~scanf("%d",&n))
{
first=1;
for(int i=0;i<n;i++) scanf("%d",&po[i]); // 后序结点
// for(int i=0;i<n;i++) scanf("%d",&pr[i]); // 先序结点
for(int i=0;i<n;i++) scanf("%d",&mid[i]); // 中序结点
int rt=mid_po_build(0,n-1,0,n-1); // 中+后,返回根节点
// int rt=mid_pr_build(0,n-1,0,n-1); // 中+先,返回根节点
bfs(rt); // 层序遍历
// preT(rt); // 先序遍历
// puts("");
// postT(rt); // 后序遍历
// puts("");
// midT(rt); // 中序遍历
// puts("");
}
return 0;
}
简化版:
#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a);
using namespace std;
typedef long long ll;
const int maxn=50;
int mid[maxn],po[maxn],pr[maxn];
int first;
struct node
{
int l,r;
}T[maxn];
int mid_pr_build(int la,int ra,int lb,int rb)
{
if(la>ra) return 0;
int rt=pr[lb];
int p1=la,p2;
while(mid[p1]!=rt) p1++;
p2=p1-la;
T[rt].l=mid_pr_build(la,p1-1,lb+1,lb+p2);
T[rt].r=mid_pr_build(p1+1,ra,lb+p2+1,rb);
return rt;
}
int mid_po_build(int la,int ra,int lb,int rb)
{
if(la>ra) return 0;
int rt=po[rb];
int p1=la,p2;
while(mid[p1]!=rt) p1++;
p2=p1-la;
T[rt].l=mid_po_build(la,p1-1,lb,lb+p2-1);
T[rt].r=mid_po_build(p1+1,ra,lb+p2,rb-1);
return rt;
}
void bfs(int rt)
{
queue<int> q;
vector<int> v;
q.push(rt);
while(!q.empty())
{
int w=q.front();
q.pop();
v.push_back(w);
if(T[w].l!=0) q.push(T[w].l);
if(T[w].r!=0) q.push(T[w].r);
}
int len=v.size();
for(int i=0;i<len;i++)
printf("%d%c",v[i],i==len-1?'\n':' ');
}
void preT(int rt)
{
if(rt==0) return;
printf(first?first=0,"%d":" %d",rt);
preT(T[rt].l);
preT(T[rt].r);
}
void midT(int rt)
{
if(rt==0) return;
midT(T[rt].l);
printf(first?first=0,"%d":" %d",rt);
midT(T[rt].r);
}
void postT(int rt)
{
if(rt==0) return;
postT(T[rt].l);
postT(T[rt].r);
printf(first?first=0,"%d":" %d",rt);
}
int main()
{
int n;
while(~scanf("%d",&n))
{
first=1;
for(int i=0;i<n;i++) scanf("%d",&po[i]);
// for(int i=0;i<n;i++) scanf("%d",&pr[i]);
for(int i=0;i<n;i++) scanf("%d",&mid[i]);
int rt=mid_po_build(0,n-1,0,n-1);
// int rt=mid_pr_build(0,n-1,0,n-1);
bfs(rt);
// preT(rt);
// postT(rt);
// midT(rt);
}
return 0;
}