1043 Is It a Binary Search Tree (二叉搜索树建树,性质)

题意:给定一个二叉树的前序遍历,判断是否为二叉搜索树

(碎碎念:一直拿不到满分,尝试了多种解法,最后挑了一个最常规的解法去一直debug才满分通过了,,这题花费了快4个小时了,,哭死)

解法一:

既然给定了二叉搜索树的所有结点,那第一反应可能会是先将这些结点构建成一个二叉搜索树(正好学到了二叉搜索树的建树)。再前序遍历一下这个二叉树(两次遍历,分别是根左右与根右左遍历),判断是不是与题目给定的遍历一样,然后输出就行。

教训:构造函数要写规范一些,空指针参数也要写,初始化要记得赋初值(一直段错误所得的教训)

#include<bits/stdc++.h>
using namespace std;
struct node{
    int val;
    node* l;
    node* r;
    //构造函数,为了方便判断,需要设左右结点为空指针
    node(int x):val(x),l(nullptr),r(nullptr){}
};
vector<int>post,pre,nums;

void insert(node*& nod,int val){//涉及更改该结点的数据,故需要使用该结点的引用
    if(nod==nullptr){
        nod=new node(val);
        return ;
    }
    if(val<nod->val) insert(nod->l,val);
    else insert(nod->r,val);
}
void preorder(node* nod,int type){
    if(nod==nullptr)return ;
    pre.push_back(nod->val);
    if(type==0){
        preorder(nod->l,type);
        preorder(nod->r,type);
    }
    else {
        preorder(nod->r,type);
        preorder(nod->l,type);
    }
    post.push_back(nod->val);
}
int main(){
    int n;cin>>n;
    node* root=nullptr;//初始要设为空,不然会段错
    for(int i=0;i<n;i++){
        int a;cin>>a;
        nums.push_back(a);
        insert(root,a);
    }
    preorder(root,0);
    if(pre==nums){
        cout<<"YES"<<endl;
        int flag=0;
        for(auto x:post){
            if(flag)cout<<" ";
            cout<<x;flag=1;
        }
        return 0;
    }
    pre.clear();post.clear();
    preorder(root,1);
    if(pre==nums){
        cout<<"YES"<<endl;
        int flag=0;
        for(auto x:post){
            if(flag)cout<<" ";
            cout<<x;flag=1;
        }
        return 0;
    }
    cout<<"NO";
}

解法二:

涉及到二叉搜索树的一个性质:即二叉搜索树的中序遍历为所有结点的从小到大(镜像为从大到小)的排序。故可以将问题转化为:

已知中序遍历与前序遍历构建二叉树,判断是否为二叉搜索树 

友情链接:已知:先序与中序||后序与中序||先序与后序,求二叉树-CSDN博客

解法三:

最直接的解法,也是我最开始的写法,存在很多注意点,问题很多,不太推荐。按理应该能过,但是我最后还是放弃了这种解法。即可以把问题转化为:

已知该树是二叉搜索树,根据前序遍历尝试构建二叉树。判断是否能够将该树成功构建。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值