PAT甲1043 Is It a Binary Search Tree前序中序构造二叉搜索树/递归实现/后序遍历

题目描述

原题
大概意思就是给你一个序列,可能是前序遍历序列(左根右)或者是镜像前序遍历序列(右根左),让你判断是不是有效的遍历序列,并且输出这棵树后序遍历序列

思路

  • 方法1:先用插入法利用所给序列构造树,再判断正确的前序序列或者镜像前序序列与所给序列是否一致
    • 代码较多,过程比较繁琐
  • 方法2:利用二叉搜索树的性质:递增排序后的结点顺序就是中序遍历序列,而知道中序和前序就能创建一棵树

AC代码(方法2)

#include<bits/stdc++.h>
using namespace std;
int preOrder[1010],inOrder[1010];
int postOrder[1010];
int Index;  //存储后序遍历序列的数组的下标
/* 前序与中序遍历构造树 */
bool buildTree(int ps, int pe, int is, int ie){
    //结束条件
    if(ps>pe) return true;
    int root = preOrder[ps];
    //假定给的是前序序列 判断其是否合法
    int pos = -1;
    for(int i = is;i<=ie;++i){
        if(inOrder[i]==root){
            pos = i;
            break;
        } 
    }
    if(pos == -1) return false;
    
    int leftLen = pos-is;
    int rightLen = ie-pos;
    //构建左子树
    if(!buildTree(ps+1,ps+leftLen, is,pos-1)) return false;
    //构建右子树
    if(!buildTree(pe-rightLen+1,pe, pos+1,ie)) return false;
    
    postOrder[Index++] = root;
    return true;
}
/* 镜像前序和中序构造树 */
bool buildTreeMirr(int ps, int pe, int is, int ie){
    //结束条件
    if(ps>pe) return true;
    int root = preOrder[ps];
    //假定给的是镜像前序序列 判断其是否合法
    int pos = -1;
    for(int i = is;i<=ie;++i){
        if(inOrder[i]==root){
            pos = i;
            break;
        } 
    }
    if(pos == -1) return false;
    
    int leftLen = pos-is;
    int rightLen = ie-pos;
    //构建右子树 !注意顺序
    if(!buildTreeMirr(ps+1,pe-leftLen,pos+1,ie)) return false;
    //构建左子树
    if(!buildTreeMirr(ps+rightLen+1,pe,is,pos-1)) return false;
     
    postOrder[Index++] = root;
    return true;
}

int main(){
    int N; 
    cin>>N;
    for(int i = 0;i<N;++i){
        cin>>preOrder[i];
        inOrder[i] = preOrder[i];
    }
    sort(inOrder,inOrder+N);  //升序排列
    if(buildTree(0,N-1,0,N-1)||buildTreeMirr(0,N-1,0,N-1)){
        cout<<"YES"<<endl;
        cout<<postOrder[0];
        for(int j=1;j<N;++j)
            cout<<" "<<postOrder[j];
    }else
        cout<<"NO"<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值