• GPLT L2-006 树的遍历(二叉树)


    题意:

    给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。

    思路:

    后序遍历序列 = 左子树遍历序列 + 右子树遍历序列 + 根节点。

    中序遍历序列 = 左子树遍历序列 + 根节点 + 右子树遍历序列。

    找到根节点,再利用根节点计算新的后、中遍历序列端点。

    Tips:

    注意建树时传根节点的引用。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int M=35;
    int n,a[M],b[M];//a数组储存后序遍历,b数组储存中序遍历
    
    map<int,int> posb;//后序遍历中某点在中序遍历中的位置
    
    struct Bt{//二叉树结点
        int v;
        Bt *l,*r;
    }*root;
    
    void build_tree(Bt* & rt,int l1,int r1,int l2,int r2){//l1~r1为该树的后序遍历序列区间,l2~r2为中序遍历序列区间。
        if(l1>r1||l2>r2){//若不存在有效遍历
            rt=nullptr;
            return;
        }
        rt=new(Bt);
        rt->v=a[r1];//后序倒数第一个即为该子树的根节点
        int mid=posb[a[r1]];//该端点在中序遍历中的位置
        int len=mid-l2;//左子树的长度
        build_tree(rt->l,l1,l1+len-1,l2,mid-1);//递归建立左子树
        build_tree(rt->r,l1+len,r1-1,mid+1,r2);//递归建立右子树
    }
    
    void Print_level(Bt* t){
        queue<Bt*> q;
        cout<<(t->v);
        if(t->l!=nullptr) q.push(t->l);
        if(t->r!=nullptr) q.push(t->r);
        while(!q.empty()){
            Bt* t=q.front();
            q.pop();
            if(t!=nullptr){
                cout<<' '<<(t->v);
                if(t->l!=nullptr) q.push(t->l);
                if(t->r!=nullptr) q.push(t->r);
            }
        }
    }
    
    int main(){
        cin>>n;
        for(int i=0;i<n;i++)
            cin>>a[i];
        for(int i=0;i<n;i++){
            cin>>b[i];
            posb[b[i]]=i;
        }
        build_tree(root,0,n-1,0,n-1);
        Print_level(root);
        return 0;
    }

     最初的做法:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int M=35;
    
    struct Bt{
        int v;
        Bt *l,*r;
    };
    
    int n,a[M],b[M];//a数组储存后序遍历,b数组储存中序遍历 
    map<int,int> posa,posb;//某值在后序、中序遍历中的位置
    
    Bt *root;
    
    void build_node(Bt* & pre,int last,int l,int r){//last为根节点的位置,l~r为中序遍历的左右端点
        pre=new(Bt);
        pre->v=a[last];
    
        int mid=posb[a[last]];//查找在中序遍历的位置
        int last1=-1,last2=-1;
        int l1=l,r1=mid-1;//计算根节点两边区间的端点
        int l2=mid+1,r2=r;
    
        for(int i=l1;i<=r1;i++)//枚举该子树结点在后序遍历中的位置,最大值即为该子树根节点的位置
            last1=max(last1,posa[b[i]]);
        for(int i=l2;i<=r2;i++)
            last2=max(last2,posa[b[i]]);
    
        if(l1<=r1)//如果中序遍历区间有效,继续建立子树结点
            build_node(pre->l,last1,l1,r1);
        else
            pre->l=nullptr;
        if(l2<=r2)
            build_node(pre->r,last2,l2,r2);
        else
            pre->r=nullptr;
    }
    
    void Print_level(Bt* t){
        queue<Bt*> q;
    
        cout<<(t->v);
        if(t->l!=nullptr) q.push(t->l);
        if(t->r!=nullptr) q.push(t->r);
    
        while(!q.empty()){
            Bt* t=q.front();
            q.pop();
            
            if(t!=nullptr){
                cout<<' '<<(t->v);
                if(t->l!=nullptr) q.push(t->l);
                if(t->r!=nullptr) q.push(t->r);
            }
        }
    }
    
    int main()
    {
        cin>>n;
    
        for(int i=0;i<n;i++){
            cin>>a[i];
            posa[a[i]]=i;
        }
    
        for(int i=0;i<n;i++){
            cin>>b[i];
            posb[b[i]]=i;
        }
    
        build_node(root,n-1,0,n-1);
    
        Print_level(root);
    
        return 0;
    }
  • 相关阅读:
    51nod1331 狭窄的通道
    noip2016 提高组
    noip2016 普及组
    noip车站分级 拓扑排序
    【NOIP1999】邮票面值设计 dfs+dp
    视频智能分析平台EasyCVR衍生版视频管理平台网页导航栏activeNav的背景照片异常的处理方式
    TSINGSEE青犀视频智能分析平台EasyCVR中性版本如何自定义平台内信息的变更?
    人脸识别/车牌识别视频智能分析系统EasyCVR通过接口GetApiV1Devices调用获取设备信息不成功原因分析
    超低延迟直播系统Webrtc编译android报错The installation of the Chrome OS default fonts failed问题
    超低延时安防直播系统webrtc-client测试推送多路视频流关闭其中一路后所有推流都关闭问题解决
  • 原文地址:https://www.cnblogs.com/Kanoon/p/12489795.html
Copyright © 2020-2023  润新知