L2-004. 这是二叉搜索树吗?
一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,
其左子树中所有结点的键值小于该结点的键值;
其右子树中所有结点的键值大于等于该结点的键值;
其左右子树都是二叉搜索树。
所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。
给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。
题解:
首先根据这个序列递归构建一棵二叉搜索树,之后分别跑一遍正常的前序遍历和镜像的前序遍历,判断是否有符合的答案。
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
#define MAX 1005
int pre[MAX] , la[MAX] ,jing[MAX], n;
int tt[MAX] , num , t , ans[MAX];
struct node
{
int l , r;
int val;
}tree[MAX];
//采用递归建树,kk为当前建树已经跑到了输入序列数组的第几号元素
void build(int kk)
{
if(kk>n) return;
tree[++num].val = tt[kk];
tree[num].l = -1;
tree[num].r = -1;
int i = 1 ;
while(1)
{
//在左子树中插入叶子
while(tt[kk]<tree[i].val && tree[i].l != -1)
i = tree[i].l;
if(tt[kk] < tree[i].val && tree[i].l == -1)
{
tree[i].l = num ;
break;
}
//在右子树中插入叶子
while(tt[kk]>= tree[i].val && tree[i].r != -1)
i = tree[i].r;
if(tt[kk] >= tree[i].val && tree[i].r == -1)
{
tree[i].r = num ;
break ;
}
}
//递归构建下一个节点
build(kk+1);
return ;
}
//获得前序遍历的序列
void get_pre(int k)
{
pre[++t] = tree[k].val ;
if(tree[k].l!= -1) get_pre(tree[k].l);
if(tree[k].r!= -1) get_pre(tree[k].r);
return;
}
//获得镜像二叉搜索树前序遍历的序列
void get_jing(int k)
{
jing[++t] = tree[k].val;
if(tree[k].r!=-1) get_jing(tree[k].r);
if(tree[k].l!=-1) get_jing(tree[k].l);
return;
}
//获得二叉搜索树后序遍历的结果
void get_la(int k)
{
if(tree[k].l != -1) get_la(tree[k].l);
if(tree[k].r != -1) get_la(tree[k].r);
ans[++t] = tree[k].val;
}
//获得镜像二叉搜索树后序遍历的结果
void get_la2(int k)
{
if(tree[k].r!= -1) get_la2(tree[k].r);
if(tree[k].l!= -1) get_la2(tree[k].l);
ans[++t] = tree[k].val;
}
//输出函数
void prin()
{
for(int i = 1 ; i <= n ; i ++)
{
if(i == n) printf("%d\n" , ans[i]) ;
else printf("%d " , ans[i]) ;
}
}
bool check()
{
int flag1 = 0 , flag2 = 0 ;
for(int i = 1 ; i <= n ; i ++)
{
if(tt[i] != pre[i])
{
flag1 = 1 ;
break;
}
}
if(!flag1)
{
printf("YES\n");
t = 0;
get_la(1);
prin();
}
else
{
for(int i = 1 ; i <= n ; i ++)
{
if(tt[i] != jing[i])
{
flag2 = 1 ;
break ;
}
}
if(!flag2)
{
printf("YES\n");
t = 0;
get_la2(1);
prin();
}
}
if(flag1 && flag2) printf("NO\n");
}
int main()
{
scanf("%d" , &n) ;
for(int i = 1 ; i <= n ; i ++)
{
scanf("%d" , &tt[i]);
}
num = 1 ;
tree[1].val = tt[1] ;
tree[1].l = -1 ;
tree[1].r = -1 ;
build(2);
t = 0;
get_pre(1);
t = 0;
get_jing(1);
check();
return 0;
}