题目链接
思路
- 我自己的思路是:后序遍历的顺序是,左右根,因为是完全二叉树,所以我可以确定左右子树的结点个数,就由此递归建树。我这样写稍微麻烦点。
- 还有一种做法就是,完全二叉树的后序遍历,是左右根的顺序遍历,我们可以左右根的去递归输入,这样得到的顺序就是层序遍历的结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/dc608be9861447fbb580a47e3e903da1.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARWNob19hYw==,size_19,color_FFFFFF,t_70,g_se,x_16)
AC代码1
#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x; i<=y; ++i)
#define per(i,x,y) for(int i=x; i>=y; --i)
#define pushk push_back
#define popk pop_back
#define mem(a,b) memset(a,b,sizeof a)
#define ll long long
#define lp p<<1
#define rp p<<1|1
#define endl '\n'
using namespace std;
const int N = 1e4+9;
int post[N];
struct Tree{
int l,r;
}tr[N];
int build(int root,int l,int r){
if(l>r) return 0;
if(l==r) return l;
int n = r-l+1;
int t=1,x=0;
while(t-1<n){
t<<=1;
x++;
}
int suml =0,sumr=0;
if(x) suml=((1<<(x-1))-2)/2;
int tmp1 = 1<<(x-1),tmp2=n-(1<<(x-1))+1;
suml+=min(tmp2,tmp1/2);
if(l<=l+suml-1) tr[root].l=build(l+suml-1,l,l+suml-1);
if(l+suml<=r-1) tr[root].r=build(r-1,l+suml,r-1);
return root;
}
void level(int rt){
queue<int> q;
q.push(rt);
while(q.size()){
int tmp = q.front();
q.pop();
if(tmp!=rt) cout<<" ";
cout<<post[tmp];
if(tr[tmp].l) q.push(tr[tmp].l);
if(tr[tmp].r) q.push(tr[tmp].r);
}
}
int main() {
int n;
cin>>n;
rep(i,1,n) cin>>post[i];
build(n,1,n);
level(n);
return 0;
}
AC代码2
#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x; i<=y; ++i)
#define per(i,x,y) for(int i=x; i>=y; --i)
#define pushk push_back
#define popk pop_back
#define mem(a,b) memset(a,b,sizeof a)
#define ll long long
#define lp p<<1
#define rp p<<1|1
#define endl '\n'
using namespace std;
const int N = 1e4+9;
int level[N],post[N];
int n,tt;
void build(int x){
if(x>n) {
return ;
}
build(2*x);
build(2*x+1);
cin>>level[x];
}
int main() {
cin>>n;
build(1);
rep(i,1,n){
cout<<level[i];
if(i<n) cout<<" ";
}
return 0;
}