【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\n",ans[n-1]);
    }

    return 0;
}
View Code

 

posted @ 2018-03-13 16:16  山枫叶纷飞  阅读(239)  评论(0编辑  收藏  举报