题目链接

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

输入格式:

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

输出格式:

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

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

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

分析:
给定一棵二叉树的前序和中序序列,可以唯一的确定一棵二叉树。

所谓的层次遍历的序列就是要按照从上到下从左到右的顺序输出来。但这里眼球镜面反转后在输出层次遍历的序列,我们一般在根据前序和中序确定一棵树的时候,先递归这棵树的左子树再递归右子树,但如果我们现在先递归右子树再递归左子树,这样每次递归的根节点的出现序列就是镜面反转后的序列。

代码:

#include <iostream>
#include<cstring>
#include<stdio.h>
using namespace std;
int post[35],in[35],pre[35],level[35];
int N=0;
//l1~r1前序的区间,l2~r2中序的区间
void postTranverse(int l1,int r1,int l2,int r2,int id)
{
    if(l1>r1||l2>r2) return;
    int i,len1,len2;
    for(i=l2; i<=r2; i++)
    {
        if(pre[l1]==in[i])//从中序中找到当前的根节点
        {
            level[N]=id;
            post[N++]=in[i];
            len1=i-l2;//左子树的长度
            len2=r2-i;//右子树的长度
            break;
        }
    }
    postTranverse(r1-len2+1,r1,i+1,r2,id+1);//递归右子树
    postTranverse(l1+1,l1+len1,l2,i-1,id+1);//递归左子树

}
int main(int argc, char** argv)
{
    int n,i,j;
    cin>>n;
    for(i=0; i<n; i++)
    {
        scanf("%d",&in[i]);//中序遍历序列
    }
    for(i=0; i<n; i++)
    {
        scanf("%d",&pre[i]);//前序遍历序列
    }
    memset(level,-1,sizeof(level));
    postTranverse(0,n-1,0,n-1,0);
    int t=1;
    printf("%d",post[0]);
    for(i=1; i<n; i++)
    {
        for(j=1; j<n; j++)
        {
            if(level[j]==t)
            {
                printf(" %d",post[j]);
            }
        }
        ++t;
    }
    return 0;
}
posted on 2018-03-18 15:16  渡……  阅读(707)  评论(0编辑  收藏  举报