• 【PAT甲级】1119 Pre- and Post-order Traversals(前序后序转中序)


    【题目链接】

    【题意】

    根据二叉树的前序和后序序列,如果中序序列唯一,输出Yes,如果不唯一输出No,并输出这个中序序列。

    【题解】

    众所周知,二叉树是不能够根据前序和中序建立的,为什么呢?首先需要明确先序序列的遍历顺序是:根左右,后序序列的遍历顺序是:左右根。

    然后我们来说一下这个样例(为了更好的说明不唯一性,没有用题目给出的样例):

    前序:1 4 6 3 2 5 7

    后序:3 6 4 5 7 2 1

    首先1肯定是整棵二叉树的根节点,然后根据前序序列我们可以知道4是1的子树(此时还不确定是左子树还是右子树),然后可以得到在后序序列中4的位置,由于后序序列的遍历顺序是左右根,那么很容易可以确定3和6肯定是4的子节点,这个时候我们可以知道已4为根节点的子节点有2个(代码中也就是num),然后到前序序列去算,发现prer-prel - 1(也就是去掉1 4 )发现大于num,由于前序遍历序列是根左右,所以prer - prel -1 - num > 0不就说明去掉左子树之外还存在节点嘛,那我们刚才的以4为根节点的树就是1的左子树,2 5 7即是右子树。

    然后我们继续递归(也就是说把刚才的序列分成左区间(前序 4 6 3 后序 3 6 4)和右区间(前序2 5 7 后序5 7 2)),然后我们来看左子树吧,这时候可以知道6是4的子树,到后序序列里找到6,那么可以确定3是6的子节点,这时我们可以知道以6位根节点的子节点有1个,然后发现前序序列中也只有1个3,这时候我们就无法确定6是4的左子树还是右子树了。

    【代码】

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 35;
    int pre[maxn], post[maxn];
    int f = 1;
    vector<int>v;
    void getorder(int prel, int prer, int postl, int postr)
    {
        if (prel == prer)
        {
            v.push_back(pre[prel]);
            return;
        }
        int a = pre[prel + 1];
        int postidx = postl;
        while(post[postidx] != a && postidx <= postr)postidx++;
        int num = postidx - postl;//以a为根节点的子树的节点数
        if (prer - prel - 1 == num)f = 0;
        
        /*在前序序列中,如果以pre[prel]为根节点的子树的节点数-a这个节点等于num,4
        那么久无法判断a是在pre[prel]的左子树还是右子树,这里我们默认为左子树*/
        getorder(prel + 1, prel + num + 1, postl, postidx);
        
        v.push_back(pre[prel]);
        
        /*在前序序列中,如果以pre[prel]为根节点的子树的节点数-a这个节点大于num,
        因为前序的遍历序列是根左右,那么就说明以pre[prel]为根的树还有右子树*/
        if (prer - prel  - 1> num)
            getorder(prel + num + 2, prer, postidx + 1, postr - 1);
    }
    int main()
    {
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
            scanf("%d", &pre[i]);
        for (int i = 0; i < n; i++)
            scanf("%d", &post[i]);
        getorder(0, n - 1, 0, n - 1);
        if(f)printf("Yes
    ");
        else printf("No
    ");
        printf("%d", v[0]);
        for (int i = 1; i < n; i++)
            printf(" %d", v[i]);
        printf("
    ");
    }
  • 相关阅读:
    5.2 i++
    5.1 赋值语句
    Implement Queue using Stacks
    Binary Tree Paths
    Single Number III
    Ugly Number
    SurfaceHolder.Callback
    intellj(idea) 编译项目时在warnings 页签框里 报 “xxx包不存在” 或 “找不到符号” 或 “未结束的字符串字面值” 或 “需要)” 或 “需要;”等错误提示
    Hibernate添加日志--log4j
    java实现网页验证码
  • 原文地址:https://www.cnblogs.com/z1014601153/p/11369941.html
Copyright © 2020-2023  润新知