zoukankan      html  css  js  c++  java
  • TOJ 5225: 玩转二叉树

    传送门:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=5225

    时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte

    描述

    给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数 

    输入

    输入第一行给出一个正整数N(N≤30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。

    输出

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

    样例输入

    样例输出

     

    思路:构树:根据先序遍历中的值,去中序遍历中分割左右子树,然后递归构建二叉树

       交换左右孩子:类似于冒泡排序中的交换,把一个根节点的左右孩子交换一下,之后也是递归对左右孩子的都进行交换(其实也可以不用交换的,入队列的时候先入右孩子,再入左孩子即可达到跟交换一样的效果)

       层次遍历:用到的是STL里面的queue。先入根节点,如果之前执行过交换,那么之后分别加入左孩子和右孩子,然后弹出根节点,直到队列为空,即遍历完所有节点。如果没执行交换,那么先加入右孩子,再左孩子。

         输出时注意行末不能留空格。

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    #define LL long long
    using namespace std;
    typedef struct tree{
        struct tree* left;
        struct tree* right;
        int data;
    }point;
    int a[1000],b[1000],flag = 0;
    tree *creat(int preL,int preR,int inL,int inR){
        if(preL > preR)return NULL;
        tree *root = new tree;
        root->data = a[preL];
        int k;
        for(k = inL;k <= inR ;k++){
            if(b[k] == a[preL])break;
        }
        //找到中序遍历中跟先序遍历相同 数据的点,即利用中序遍历,分割左右子树,再递归分割 
        int numLeft = k - inL;
        root->left  = creat(preL+1,preL+numLeft,inL,k-1);
        root->right = creat(preL+numLeft+1,preR,k+1,inR);
        //递归构建左右子树 
        return root;
    }
    //由中序和先序遍历构树过程 
    void change(tree *root){
        if(root==NULL)return;
        tree *temp;
    
        temp = root->left;
        root->left = root->right;
        root->right = temp;
        
        //递归交换左右节点
        change(root->left);
        change(root->right);
    }
    void order(tree *root){
        if(root==NULL)return;
        queue<tree>q;
        q.push(*root);
        //队列模拟 层次遍历 
        while(!q.empty()){
            tree que = q.front();//取队头 
            (flag == 0)?printf("%d",que.data):printf(" %d",que.data);
            flag = 1;
            if(que.left!=NULL){
                q.push(*(que.left));
            }
            if(que.right!=NULL){
                q.push(*(que.right));
            }
            //先加入左结点,再加入右结点,直到队空即遍历完所有的结点,结束 
            q.pop();
        }
    }
    int main(){
        int n;
        scanf("%d",&n);
        for(int i = 0 ; i < n ; i++)scanf("%d",&b[i]);
        for(int i = 0 ; i < n ; i++)scanf("%d",&a[i]);
        tree *root = creat(0,n-1,0,n-1);
        change(root);
        order(root);
        puts("");
    }

     

  • 相关阅读:
    adb使用项目导入等
    ThreadLocal类理解
    Spring MVC MyBatis
    Spring MVC原理图
    Spring MVC返回JSON的几种方法
    Understanding REST
    链表
    存储构造题(Print Check)
    线状DP(石子归并)
    线段树(与区间有关的操作)
  • 原文地址:https://www.cnblogs.com/Esquecer/p/8495006.html
Copyright © 2011-2022 走看看