PAT L2-011.玩转二叉树(数据结构,二叉链表)

这是一篇关于PAT考试中L2-011题目的解题报告,主要涉及如何通过给定的二叉树中序和前序遍历序列,实现二叉树的镜面反转,并输出反转后的层序遍历序列。解题思路包括利用前中遍历序列构建二叉树,并进行反转操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:https://www.patest.cn/contests/gplt/L2-011

L2-011. 玩转二叉树

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越

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

输入格式:

输入第一行给出一个正整数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


解题思路:(比赛的时候,因为上次可以用数组解决,条件反射一直考虑数组,浪费了很多时间QAQ,最后还是用的链表。。。真的是服了- -)

其实根据前中遍历 找出树本身的序列并不难 我们先在前序遍历那里找出第一个元素 ,然后在 中序遍历里面找出这个元素,因为前序遍历先遍历根节点,所以在这个元素左边

就是左子树上的元素,右边就是右子树的元素。

按照样例来讲:在第二个序列找出第一个数就是4,然后在第一个序列找出4   这样根据中序遍历先左子树,然后根,最后右子树的规律 4为根(123)为左子树

(5,6,7)为右子树 ,接着 扫先序序列到1,1为根  ,1左边没有元素,故1没有左子树,右子树为(23),接着先序序列到3,3为根,(2)为左子树,接着到6,6为根。

左边的5为左子树,7为右子树,下面有丑图 0 0(好久没画图_(:з」∠)_)

  

反转的话- -很简单。翻转左子树,翻转右子树,数据结构的基本内容(忘了,自觉百度面壁去吧)

代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<set>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 10;
const int INF  = 0x7fffffff;
int pre[maxn];
int mid[maxn];
int ans[maxn+20];
int n;

typedef struct node
{
    struct node  *l  ;
    struct node  *r;
    int data;
}*treenode,node;
node tmp;
void search_(int l,int r,treenode *root)
{

    if(l>r)
        return ;
    int f= 0;
    int rt;
//    cout << 1<<endl;
    for(int j = 0 ; j < n ; j ++)
    {
        for(int i = l ; i <= r ; i ++)
            if(mid[i] == pre[j])
            {
                rt = i;
                f=1;
                break;
            }
        if(f)
            break;
    }
    *root = (treenode)malloc(sizeof(node));
//cout << 1<<endl;
    (*root)->l = NULL;
    (*root)->r = NULL;
    (*root)->data = mid[rt];
    search_(l,rt-1,&((*root)->l));
    search_(rt+1,r,&((*root)->r));
}
void re(treenode tp)
{
    treenode t;
    if(tp)
    {
        t = tp->r;
        tp->r = tp->l;
        tp->l = t;
        re(tp->l);
        re(tp->r);
    }
}
int cnt = 0;
void transfver(node *tp)
{
    queue<node *>que;
    que.push(tp);
    while(!que.empty())
    {
        tp = que.front();
        que.pop();
        if(tp->l)
        {
            que.push(tp->l);
        }
        if(tp->r)
        {
            que.push(tp->r);
        }
        ans[cnt++] = tp->data;

    }

}
int main()
{
    cin >> n;
    for(int i = 0 ; i< n ; i++)
        scanf("%d",&mid[i]);
    for(int i = 0 ; i < n; i ++)
        scanf("%d",&pre[i]);
    node *tmp;
    tmp =(treenode)malloc(sizeof(node));
    search_(0,n-1,&tmp);
//    cout << tmp ->data<<endl;
    re(tmp);
    transfver(tmp);
    for(int i = 0 ; i < cnt  - 1; i ++)
        printf("%d ",ans[i]);
    printf("%d\n",ans[cnt-1]);

    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值