【天梯赛】L2-004 这是二叉搜索树吗(经典问题C++)
解题反思
//镜像树满足:左子树>根节点>右子树
//特殊:独腿二叉树,如pre = {2,3,4},递归函数用if(root == tail) return;无法识别这种二叉树
// 用ismirror来将一般二叉树和镜像二叉搜索树的情况对应操作放在同一个函数中
L2-004 这是二叉搜索树吗? - 团体程序设计天梯赛-练习集
已知先序序列,得到后序序列:
一般已知一种序列不能唯一确定另一种序列,但结合二叉树的某些特殊性质可以
比如满二叉树,完全二叉树,二叉搜索树等
递归函数检验逻辑:
是二叉搜索树 <=> 在先序遍历中找到第一个大于根节点的值,其将pre分成了左子树和右子树
返回条件
插入检验左子树和右子树中的所有元素是否都分别小于和大于根节点的值
如果检验失败就直接跳过后面遍历return,这样post.size()!=N就反映出了检验失败的情况
后序遍历:
递归左子树
递归右子树
存下当前的根节点的值进post,就得到了后序遍历序列
#include<bits/stdc++.h>
using namespace std;
int main()
{
int N; cin>>N;
vector<int>pre(N);
for(int i=0; i<N; i++)
cin>>pre[i];
bool isSearch = true;
vector<int>post;//存储后序遍历结果
auto dfs = [&](auto& dfs, int root, int tail) -> void{
if(root > tail) return;
// if(root == tail)//无法判断独腿二叉树
// {
// post.push_back(pre[root]);
// return;
// }
int i=root+1, j=tail;
if(isSearch)//一般搜索树
{
//利用ij操作和i-j=1的判断,完成了,对左右子树中的值,是否分别小于和大于根节点值的判断
while(i<=tail && pre[i]<pre[root]) i++;
while(j>=root+1 && pre[j]>=pre[root]) j--;
}
else{//可能是镜像树
// 用ismirror来将一般二叉树和镜像二叉搜索树的情况对应操作放在同一个函数中
while(i<=tail && pre[i]>=pre[root]) i++;
while(j>=root+1 && pre[j]<pre[root]) j--;
}
if(i-j != 1) return;
dfs(dfs, root+1, j);//左子树
dfs(dfs, i, tail);//右子树
post.push_back(pre[root]);
};
dfs(dfs, 0, N-1);
if(post.size()!=N)
{
post.clear();
isSearch = false;
dfs(dfs, 0, N-1);
}
if(post.size() == N)
{
cout<<"YES"<<endl;
for(int i=0; i<post.size(); i++)
{
cout<<post[i];
if(i == post.size()-1) cout<<endl;
else cout<<" ";
}
}
else{
cout<<"NO"<<endl;
}
return 0;
}