题目描述:
判断两序列是否为同一二叉搜索树序列
输入:
开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树。
输出:
如果序列相同则输出YES,否则输出NO
543267
576342
0
判断两序列是否为同一二叉搜索树序列
输入:
开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树。
输出:
如果序列相同则输出YES,否则输出NO
样例输入:
2
567432543267
576342
0
样例输出:
YES
NO
算法实现一:
/*判断两个二叉排序树是否相同 */
//建树 根据前序和中序遍历序列是否相同进行判断
//由中序序列和前序或者后序序列能唯一的确定一棵树
//wa
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct BiTree{
int data;
struct BiTree * lchild;//
struct BiTree * rchild;
}BiTree;
//技巧
char str1[25],str2[25];//前序和中序序列保存于同一数组中便于比较
int size1,size2;//两个数组的大小
char *str;//方便子函数的编写
int *size;// 指示当前的操作的字符串数组
BiTree *Insert(BiTree *p,int x){//构建二叉排序树
if(p==NULL){
p=(BiTree *)malloc(sizeof(BiTree));
p->data=x;
p->lchild=p->rchild=NULL;
return p;
}
else if(x<p->data)
p->lchild=Insert(p->lchild,x);
else if(x>p->data)
p->rchild=Insert(p->rchild,x);
return p;
}
void PreOrder(BiTree *p){//前序遍历
if(p!=NULL){
str[(*size)++]=p->data+'0';
PreOrder(p->lchild);
PreOrder(p->rchild);
}
}
void InOrder(BiTree *p){//中序遍历
if(p!=NULL){
InOrder(p->lchild);
str[(*size)++]=p->data+'0';
InOrder(p->rchild);
}
}
int main(){
int n,i;
char src[10];
freopen("test.txt","r",stdin);
while(scanf("%d",&n)!=EOF){
if(n==0) break;
scanf("%s",src);
BiTree *tree=NULL;
for(i=0;src[i]!=0;i++){
tree=Insert(tree,src[i]-'0');
}
size1=0;
str=str1;
size=&size1;
PreOrder(tree);
InOrder(tree);
str1[size1]=0;//!!!
for(i=0;i<n;i++){
BiTree *p=NULL;
int j;
scanf("%s",src);
for(j=0;src[j]!=0;j++){
p=Insert(p,src[j]-'0');
}
size2=0;
str=str2;
size=&size2;
PreOrder(p);
InOrder(p);
str2[size2]=0;
printf("%s\n",strcmp(str1,str2)==0 ?"Yes":"NO");
}
}
fclose(stdin);
return 0;
}
特别注意:
1.指针变量定义时就要初始化为空,字符串数组输出前要在结尾加上字符串结束符;
2.这是本题的基本思路,基础的数据结构要掌握牢固!
算法实现二:
/* 判断两个二叉排序树是否相同 */
//用静态数组模拟二叉排序树的建立过程
void creat(char a[],int x[]){//模拟二叉排序树的插入过程
int i,j,temp;
for(i=0;a[i]!=0;i++){
temp=a[i]-'0';
for(j=1;j<1024;){
if(x[j]==-1){
x[j]=temp;
break;
}
else if(temp>x[j]){
j=2*j+1;
}
else{
j=2*j;
}
}
}
}
#include<stdio.h>
int main(){
int n,i,j,bb[1024],cc[1024];//静态数组;
char a[10];
freopen("test.txt","r",stdin);
while(scanf("%d",&n)!=EOF){
scanf("%s",a);
for(i=1;i<1024;i++){//数组元素均初始化为-1
bb[i]=-1;
}
creat(a,bb);//建立被比较字符串的二叉排序树
for(j=0;j<n;j++){//n次比较 注意ij指针的使用 容易乱
scanf("%s",a);
for(i=1;i<1024;i++){
cc[i]=-1;
}
creat(a,cc);
for(i=0;i<1024;i++){
if(bb[i]!=cc[i])
break;
}
if(i==1024)
printf("YES\n");
else
printf("NO\n");
}
}
fclose(stdin);
return 0;
}
特别注意:
1.这是借鉴别人的算法思想,根据二叉排序树的性质,采用静态数组来模拟二叉树排序的建立过程,数组下标代表了满二叉树时的对应结点;
2.数组为什么要用1024大小?题目中说明字符串即结点个数不大于10,即在极端情况下,树的深度为10 ,那么树的最大结点应为1024;
3.遇到这类题目时,在没有更好的办法时再建树,建树一定是没有更好的算法的下下之策。