zoukankan      html  css  js  c++  java
  • PAT A1119 Pre- and Post-order Traversals [前序后序求中序]

    题目描述

    链接
    给出一棵树的结点个数n,以及它的前序遍历和后序遍历,输出它的中序遍历,如果中序遍历不唯一就输出No,且输出其中一个中序即可,如果中序遍历唯一就输出Yes,并输出它的中序

    分析

    • 分析题目所给的正反样例,可以发现,最后递归到单一子树后,左根是它,右根也是它,就不唯一了。此时,可以随便指定为右孩子或者左孩子
    • 具体来说,对先序从前往后找,对后序从后往前找,找到左右子树的根,从而确定左右子树的范围进行递归
    • 当递归到某处,发现当前结点!!的左子树的根和右子树的根重合了(i==prel+1)话((i)是右子树的根,(prel)是当前根结点,(prel+1)是左子树的根),则向下递归时,只向右子树递归
    • 另外还要注意,递归到最后,只剩一个结点即(prel==prer),就直接return root了,不用再向下递归了
    • 画下图,模拟下过程就好
    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 40;
    int pre[maxn],post[maxn];
    int n;
    struct node{
        int data;
        node *lchild,*rchild;
    };
    //root为后序序列的根结点,st,ed为先序的范围
    vector<int> ans;
    bool flag = true;
    node *create(int prel, int prer, int postl, int postr){
        if(prel > prer) return NULL;
        //建立此状态下的根结点
        node *root = new node;
        root->data = pre[prel];
        root->lchild = NULL;
        root->rchild = NULL;
        if(prel==prer){
            return root;
        }
        //找左右子树的范围
        //在先序里面找到右子树根节点的位置
        int i;
        for(i=prel;i<=prer;i++){
            if(post[postr-1] == pre[i]){
                break;
            }
        }
        if(i - prel > 1){
            //左子树的范围: prel+1,i-1, 长度i-1-prel 
            root->lchild = create(prel+1,i-1,postl,postl+i-prel-2); //左子树的范围
            //右子树的范围: 
            root->rchild = create(i, prer, postl+i-prel-1, postr-1);
        }else{ //i==prel+1 即左右子树的根节点重合了
            flag = false;
            root->rchild = create(i, prer, postl+i-prel-1, postr-1); //就当成右子树
        }
        return root;
    }
    
    void inorder(node *root){
        if(!root) return;
        inorder(root->lchild);
        ans.push_back(root->data);
        inorder(root->rchild);
    }
    
    int main(){
        cin>>n;
        for(int i=0;i<n;i++) cin>>pre[i];
        for(int i=0;i<n;i++) cin>>post[i];
        node *root = create(0,n-1,0,n-1);
        inorder(root);
        if(flag) printf("Yes
    ");
        else printf("No
    ");
        for(int i=0;i<ans.size();i++){
            if(i==0)printf("%d",ans[i]);
            else printf(" %d",ans[i]);
        }
        printf("
    ");
    }
    
  • 相关阅读:
    (最短路)2017 计蒜之道 复赛 D. 百度地图导航
    13 树的应用-并查集
    12 二叉树-链式存储-二叉排序树(BST)
    11 二叉树-链式存储-先序遍历、中序遍历、后序遍历和层序遍历的非递归算法实现
    10 二叉树-链式存储-递归遍历
    9 线性表-队列-链式存储
    8 线性表-循环队列-顺序存储
    操作系统-页式虚拟存储器管理系统设计
    杂谈:Windows操作系统的介绍与对Win8操作系统市场反响冷淡原因的分析
    一学期积累下来的SQL语句写法的学习
  • 原文地址:https://www.cnblogs.com/doragd/p/11290774.html
Copyright © 2011-2022 走看看