PAT1020 Tree Traversals(后序中序求层序)

16 篇文章 0 订阅

已知后序和中序,求层次遍历

法一:标准建树+BFS版

#include <iostream>
#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<n;i++)
#define sca(x) scanf("%d",&x)
#define sca2(x,y) scanf("%d%d",&x,&y)
#define scl(x) scanf("%lld",&x)
#define pri(x) printf("%d\n",x)
#define pri2(x,y) printf("%d %d\n",x,y)
#define prs(x) printf("%s\n",(x))
#define prl(x) printf("%lld\n",x)
#define ll long long
#define PII pair<int,int>
#define eps 1e-6
#define inf 1e17
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=1e6+5;
struct node{
    int data;
    node* lson;
    node* rson;
}tree[maxn];
int n;
int pre[maxn],in[maxn],post[maxn];
node *build(int inL,int inR,int postL,int postR){
    if(postL>postR) return NULL;
    node* root=new node;
    root->data=post[postR];
    int k=inL;
    while(in[k]!=root->data)k++;
    root->lson=build(inL,k-1,postL,postL+(k-1-inL));
    root->rson=build(k+1,inR,postL+(k-1-inL)+1,postR-1);
    return root;
}
void bfs(node *root){
    queue<node*>q;
    q.push(root);
    while(!q.empty()){
        node* p=q.front();
        q.pop();
        printf("%d",p->data);
        if(p->lson!=NULL) q.push(p->lson);
        if(p->rson!=NULL) q.push(p->rson);
        if(q.empty()) puts("");
        else printf(" ");
    }
}
int main(){
    sca(n);
    rep(i,0,n)sca(post[i]);
    rep(i,0,n)sca(in[i]);
    node* root=build(0,n-1,0,n-1);
    bfs(root);
    return 0;
}

法二:哈希表建树版

#include <iostream>
#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<n;i++)
#define sca(x) scanf("%d",&x)
#define sca2(x,y) scanf("%d%d",&x,&y)
#define scl(x) scanf("%lld",&x)
#define pri(x) printf("%d\n",x)
#define pri2(x,y) printf("%d %d\n",x,y)
#define prs(x) printf("%s\n",(x))
#define prl(x) printf("%lld\n",x)
#define ll long long
#define PII pair<int,int>
#define eps 1e-6
#define inf 1e17
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=40;

int n;
int pre[maxn],in[maxn],post[maxn];
unordered_map<int,int>l,r,pos;
int build(int inL,int inR,int postL,int postR){
    int root=post[postR];
    int k=pos[root];
    if(inL<k) l[root]=build(inL,k-1,postL,postL+(k-1-inL));
    if(k<inR) r[root]=build(k+1,inR,postL+(k-1-inL)+1,postR-1);
    return root;
}
void bfs(int root){
    queue<int>q;
    q.push(root);
    while(!q.empty()){
        int t=q.front();
        q.pop();
        printf("%d",t);
        if(l.count(t)) q.push(l[t]);
        if(r.count(t)) q.push(r[t]);
        if(q.empty()) puts("");
        else printf(" ");
    }
}
int main(){
    sca(n);
    rep(i,0,n)sca(post[i]);
    rep(i,0,n)sca(in[i]),pos[in[i]]=i;
    int root=build(0,n-1,0,n-1);
    bfs(root);
    return 0;
}

法三:不建树版,参考柳神,用index+排序来写层序遍历

#include <iostream>
#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<n;i++)
#define sca(x) scanf("%d",&x)
#define sca2(x,y) scanf("%d%d",&x,&y)
#define scl(x) scanf("%lld",&x)
#define pri(x) printf("%d\n",x)
#define pri2(x,y) printf("%d %d\n",x,y)
#define prs(x) printf("%s\n",(x))
#define prl(x) printf("%lld\n",x)
#define ll long long
#define PII pair<int,int>
#define eps 1e-6
#define inf 1e17
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=1e6+5;
struct node{
    int index,value;
};
int n;
int pre[maxn],in[maxn],post[maxn];
vector<node>v;
void dfs(int postR,int inL,int inR,int index){
    if(inL>inR) return ;
    int k=inL;
    while(in[k]!=post[postR])k++;
    v.push_back({index,post[postR]});
    dfs(postR-(inR-k+1),inL,k-1,2*index+1);
    dfs(postR-1,k+1,inR,2*index+2);
    return ;
}
bool cmp(node a,node b){
    return a.index<b.index;
}
int main(){
    sca(n);
    rep(i,0,n)sca(post[i]);
    rep(i,0,n)sca(in[i]);
    dfs(n-1,0,n-1,0);
    sort(v.begin(),v.end(),cmp);
    for(int i=0;i<v.size();i++){
        printf("%d%c",v[i].value,i==v.size()-1?'\n':' ');
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值