二叉搜索树就是左边的任何元素一定比根节点小,右边任何元素一定比根节点大或者等于根节点
10:二叉排序树
-
总时间限制:
- 1000ms 内存限制:
- 128000kB
-
描述
-
依次给出n(0<n<=100000)个整数,请你以这n个数创建一棵二叉排序树,这棵排序树的根节点为第一个数,并输出其中序遍历和后序遍历。
输入
- 共两行,第一行为整数n,第二行为n个整数 输出
- 共两行,第一行为中序遍历,第二行为后序遍历 样例输入
-
8 23 45 12 6 7 89 13 47
样例输出
-
6 7 12 13 23 45 47 89 7 6 13 12 47 89 45 23
代码如下:
#include<cstdio>
#include<algorithm>
using namespace std;
int tree[100005];
int back[100005];
int back_num;
int left[100005],right[100005];
struct TREE
{
int n;
struct TREE *left;
struct TREE *right;
};
void nomirror(int start,int end,struct TREE *p)
{
int root=tree[start];
int i,j,k,l;
int flag1=start,flag2=end;
p->n=root;
if(end-start<=1)
{
p->left=p->right=NULL;
return;
}
for(i=start+1,k=0,l=0;i<end;i++)
if(tree[i]<tree[start])
left[k++]=tree[i];
else
right[l++]=tree[i];
for(i=start+1,j=0;j<k;i++)
{
tree[i]=left[j++];
}
for(j=0;j<l;i++)
{
tree[i]=right[j++];
}
for(i=start+1;i<end;i++)
{
if(tree[i]<root)
{
flag1=i;
break;
}
}
for(i=start+1;i<end;i++)
{
if(tree[i]>=root)
{
flag2=i;
break;
}
}
if(flag1!=start)
{
p->left=(struct TREE*)malloc(sizeof(struct TREE));
nomirror(flag1,flag2,p->left);
}
else
p->left=NULL;
if(flag2!=end)
{
p->right=(struct TREE*)malloc(sizeof(struct TREE));
nomirror(flag2,end,p->right);
}
else
p->right=NULL;
}
void back_erg(struct TREE *p)
{
if(p->left!=NULL)
back_erg(p->left);
if(p->right!=NULL)
back_erg(p->right);
back[back_num++]=p->n;
}
int main()
{
int n,i,j;
struct TREE *r;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&tree[i]);
r=(struct TREE*)malloc(sizeof(struct TREE));
nomirror(0,n,r);
sort(tree,tree+n);
for(i=0;i<n-1;i++)
printf("%d ",tree[i]);
printf("%d\n",tree[i]);
back_num=0;
back_erg(r);
for(i=0;i<n-1;i++)
printf("%d ",back[i]);
printf("%d\n",back[i]);
return 0;
}
进阶一点的话,一个搜索树也可能被翻转过来,不过他还依然像个搜索树,他的中序遍历会变成降序。
L2-004. 这是二叉搜索树吗?
一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,
- 其左子树中所有结点的键值小于该结点的键值;
- 其右子树中所有结点的键值大于等于该结点的键值;
- 其左右子树都是二叉搜索树。
所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。
给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。
输入格式:
输入的第一行给出正整数N(<=1000)。随后一行给出N个整数键值,其间以空格分隔。
输出格式:
如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出“YES”,然后在下一行输出该树后序遍历的结果。数字间有1个空格,一行的首尾不得有多余空格。若答案是否,则输出“NO”。
输入样例1:7 8 6 5 7 10 8 11输出样例1:
YES 5 7 6 8 11 10 8输入样例2:
7 8 10 11 8 6 7 5输出样例2:
YES 11 8 10 7 5 6 8输入样例3:
7 8 6 8 5 10 9 11输出样例3:
NO
这道题目我的做法是先把他当成不是镜像来写,如果不符合,再去判断如果他是镜像行不行,两种都不行的话就只能是NO了。
代码如下:
#include<stdio.h>
#include<stdlib.h>
int sw,k;
int tree[1005],back[1005];
struct TREE
{
int n;
struct TREE *left;
struct TREE *right;
};
void nomirror(int start,int end,struct TREE *p)
{
int root=tree[start];
int flag1=start,flag2=end,i;
p->n=root;
if(end-start<=1)
{
p->left=p->right=NULL;
return;
}
for(i=start+1;i<end;i++)
{
if(tree[i]<root)
{
flag1=i;
break;
}
}
for(i=start+1;i<end;i++)
{
if(tree[i]>=root)
{
flag2=i;
break;
}
}
if(flag1>flag2)
{
sw=0;
return;
}
for(i=flag2;i<end;i++)
if(tree[i]<root)
{
sw=0;
return;
}
if(sw&&flag1!=start)
{
p->left=(struct TREE*)malloc(sizeof(struct TREE));
nomirror(flag1,flag2,p->left);
}
else
p->left=NULL;
if(sw&&flag2!=end)
{
p->right=(struct TREE*)malloc(sizeof(struct TREE));
nomirror(flag2,end,p->right);
}
else
p->right=NULL;
}
void mirror(int start,int end,struct TREE *p)
{
int root=tree[start];
int flag1=start,flag2=end,i;
p->n=root;
if(end-start<=1)
{
p->left=p->right=NULL;
return;
}
for(i=start+1;i<end;i++)
{
if(tree[i]>=root)
{
flag1=i;
break;
}
}
for(i=start+1;i<end;i++)
{
if(tree[i]<root)
{
flag2=i;
break;
}
}
if(flag1>flag2)
{
sw=0;
return;
}
for(i=flag2;i<end;i++)
if(tree[i]>=root)
{
sw=0;
return;
}
if(sw&&flag1!=start)
{
p->left=(struct TREE*)malloc(sizeof(struct TREE));
mirror(flag1,flag2,p->left);
}
else
p->left=NULL;
if(sw&&flag2!=end)
{
p->right=(struct TREE*)malloc(sizeof(struct TREE));
mirror(flag2,end,p->right);
}
else
p->right=NULL;
}
void back_erg(struct TREE *p)
{
if(p->left!=NULL)
back_erg(p->left);
if(p->right!=NULL)
back_erg(p->right);
back[k++]=p->n;
}
int main()
{
int n,i;
struct TREE *r;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&tree[i]);
sw=1;
r=(struct TREE*)malloc(sizeof(struct TREE));
nomirror(0,n,r);
if(sw)
{
printf("YES\n");
k=0;
back_erg(r);
for(i=0;i<n-1;i++)
printf("%d ",back[i]);
printf("%d\n",back[i]);
}
else
{
sw=1;
mirror(0,n,r);
if(sw)
{
printf("YES\n");
k=0;
back_erg(r);
for(i=0;i<n-1;i++)
printf("%d ",back[i]);
printf("%d\n",back[i]);
}
else
printf("NO\n");
}
}