题意:给定一个二叉树的前序遍历,判断是否为二叉搜索树
(碎碎念:一直拿不到满分,尝试了多种解法,最后挑了一个最常规的解法去一直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博客
解法三:
最直接的解法,也是我最开始的写法,存在很多注意点,问题很多,不太推荐。按理应该能过,但是我最后还是放弃了这种解法。即可以把问题转化为:
已知该树是二叉搜索树,根据前序遍历尝试构建二叉树。判断是否能够将该树成功构建。