7-4 是否同一棵二叉搜索树 (25 分)
作者: 陈越
单位: 浙江大学
时间限制: 400 ms
内存限制: 64 MB
代码长度限制: 16 KB
给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。
输入格式:
输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列。最后L行,每行给出N个插入的元素,属于L个需要检查的序列。
简单起见,我们保证每个插入序列都是1到N的一个排列。当读到N为0时,标志输入结束,这组数据不要处理。
输出格式:
对每一组需要检查的序列,如果其生成的二叉搜索树跟对应的初始序列生成的一样,输出“Yes”,否则输出“No”。
输入样例:
4 2
3 1 4 2
3 4 1 2
3 2 4 1
2 1
2 1
1 2
0
输出样例:
Yes
No
No
我真的服了自己
总是答案错误而且是所有测试点都错,然而在IDE里各种数据都没问题,也找不出来错误,不得已又换了种做法,还是答案错误,最后的最后,我发现,输出结果应该是Yes和No,我看成了YES和NO,就这样一直是错的,枯了。
两种方法就是存储树的方式不同,一个是定义结构体,另一种就是用数组。但是数组必须足够大。
#include <stdio.h>
#include <stdlib.h>
typedef struct TNode* BinTree;
struct TNode{
int data;
BinTree Left;
BinTree Right;
};
BinTree Insert(int x,BinTree BST)
{
if(!BST){//原树为空,生成并返回只有1个结点的树
BST=(BinTree)malloc(sizeof(struct TNode));
BST->data=x;
BST->Left=NULL;
BST->Right=NULL;
}
else{//判断插入位置
if(x<BST->data)
BST->Left=Insert(x,BST->Left);//递归插入左子树
else if(x>BST->data)
BST->Right=Insert(x,BST->Right);//递归插入右子树
}
return BST;
}
int Compare(BinTree a,BinTree b)
{
if(a==NULL&&b==NULL)//同时为空相同
return 1;
else if((a==NULL&&b!=NULL)&&(a!=NULL&&b==NULL))//不同时为空,不同
return 0;
else if(a->data!=b->data)//数值不相同,不同
return 0;
else{
int flag1 = 0;
int flag2 = 0;
flag1 = Compare(a->Left,b->Left);//判断左子树
if(flag1){//相同
flag2 = Compare(a->Right,b->Right);//在左子树相同的情况下判断右子树
if(flag2)return 1;//都相同返回1
else return 0;//右子树不同
}
else return 0;//左子树不同
}
}
int main()
{
int N,L,i,j,x;
scanf("%d",&N);
while(N){
scanf("%d",&L);
BinTree T[L+1];
for(i=0;i<=L;i++)
T[i]=NULL;
for(j=0;j<L+1;j++){
for(i=0;i<N;i++){
scanf("%d",&x);
T[j]=Insert(x,T[j]);
}
}
for(i=1;i<L+1;i++){
if(Compare(T[0],T[i]))
printf("Yes\n");
else
printf("No\n");
}
scanf("%d",&N);
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxn 1024
int a[maxn],b[maxn];//数组存储二叉树
int Insert(int data,int p,int*tree)//给输入的值找到存入数组中的下标
{
if(tree[p]==-1)
return p;
else if(tree[p]>data)
return Insert(data,2*p,tree);//到左子树上找
else
return Insert(data,2*p+1,tree);//到右子树上找
}
void Create1(int N)
{
int x,i;
memset(a,-1,sizeof(a));
for(i=1;i<=N;i++){
scanf("%d",&x);
int d=Insert(x,1,a);//从根节点开始递归查找插入位置
a[d]=x;
}
}
void Create2(int N)
{
int y,i;
memset(b,-1,sizeof(b));
for(i=1;i<=N;i++){
scanf("%d",&y);
int d=Insert(y,1,b);//从根节点开始递归查找插入位置
b[d]=y;
}
}
int Compare(int*a,int*b)//判断给定的二叉搜索树在数组中的序列与要判断的搜索树序列是否相同
{
int i;
for(i=1;i<maxn;i++){//maxn应该为1024,刚开始我写的512,N最大时(N=2^10)答案错误
if(a[i]!=b[i])
return 0;
}
return 1;
}
int main()
{
int N,L,i,j;
scanf("%d",&N);
while(N){
scanf("%d",&L);
int flag[L];
Create1(N);
for(j=0;j<L;j++){
Create2(N);
if(Compare(a,b))
flag[j]=1;
else
flag[j]=0;
}
for(i=0;i<L;i++){
if(flag[i])
printf("Yes\n");
else
printf("No\n");
}
scanf("%d",&N);
}
return 0;
}