zoukankan      html  css  js  c++  java
  • 【PAT-二叉树】L2-011. 玩转二叉树- 仅仅开100大的数组模拟即可!

    L2-011. 玩转二叉树

    给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。(我的分析:无非就是说把左子树当成右子树,把右子树当成左子树;没啥多的影响,就是输出的时候先左后右即可了)!这里假设键值都是互不相等的正整数。

    输入格式:

    输入第一行给出一个正整数N(<=30)(分析:假设它是一棵斜二叉树,它的深度上限将达到1e9! 数组是会炸的!),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。

    输出格式:

    在一行中输出该树反转后的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。

    输入样例:
    7
    1 2 3 4 5 6 7
    4 1 3 2 6 5 7
    
    输出样例:
    4 6 1 7 5 3 2

    大致思路
     1、先根据中序(左根右)和前序(根左右)来建树;
        2.然后BFS层序遍历时,按照镜像原则——反着先右子树后左子树。
     3.这题的数据真的严格,假设是一棵深度为30的二叉树,大约需要1000000000的数组大小来开! 试了几个都段错误了!在网上看了很多题解,大多都是用链表来写的!而我比较懒,又恰巧想到了一个真的简单的方法,于是乎就用数组进行实现了,并且就开到了100大!于是动手就实现了!
     
    AC代码:
    //注意,头文件私奔了!!!自行找回!
    #define  inf 0x3f3f3f3f
    using namespace std;
    #define N 108
    struct node{
        int data;
        int l,r;
    }tree[N];//用Time方式来依次记录建立的节点的序号!
    int Time;
    vector<int>ans;
    void build_tree(int root,vector<int>a,vector<int>b){//a前序b中序
        if(a.size()==0)return ;//递归调用结束的条件!
        int p=0;
        for(int i=0;i<(int)b.size();i++){
            if(b[i]==a[0]){
                p=i;break;//在中序b中的找当前根节点的下标
            }
        }
        vector<int>al,ar,bl,br;
        for(int i=1;i<=p;i++)
            al.push_back(a[i]);
        for(int i=p+1;i<=(int)a.size()-1;i++)
            ar.push_back(a[i]);
    
        for(int i=0;i<=p-1;i++)
            bl.push_back(b[i]);
        for(int i=p+1;i<=(int)b.size()-1;i++)
            br.push_back(b[i]);
    
        tree[root].data=a[0];//确定根节点(立即存储),然后递归处理
        tree[root].l=++Time;
        tree[root].r=++Time;
        build_tree(tree[root].l,al,bl);
        build_tree(tree[root].r,ar,br);
    }
    void bfs(){//层序遍历
        queue<node>Q;
        Q.push(tree[1]);
        node now;
        while(Q.size()){
            now=Q.front();Q.pop();
            if(now.data==-1)continue;//到底了!
            ans.push_back(now.data);
    
            Q.push(tree[now.r]);//镜像结构层序遍历时,先右子树后左子树
            Q.push(tree[now.l]);
        }
    }
    int main(){
        int x;
        int n;
        vector<int>a,b;
        while(scanf("%d",&n)!=EOF){
         a.clear();b.clear();
    
            for(int i=1;i<=n;i++){
                scanf("%d",&x);b.push_back(x);
            }
            for(int i=1;i<=n;i++){
                scanf("%d",&x);a.push_back(x);
            }
            for(int i=0;i<N;i++)
                tree[i].data=-1;
            Time=0;
            build_tree(++Time,a,b);
    
            ans.clear();//存结果
            bfs();
            for(int i=0;i<=n-2;i++)
                printf("%d ",ans[i]);
            printf("%d
    ",ans[n-1]);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    operator[],识别读操作和写操作
    COW写时复制
    嵌套类,PIMPL
    类型转换
    String类运算符重载,自己实现
    socket的几个配置函数
    TCP三次握手,四次挥手,状态变迁图
    运算符重载
    友元
    P4016 负载平衡问题(最小费用最大流)
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/8558028.html
Copyright © 2011-2022 走看看