描述
给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{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
方法一
思路
将被比较的树建立,然后去判断需要比较的序列是否对应着那棵树。判断的方法,循环查找每一个元素,查找过程中,如果经历了没有被标记的结点,就说明这两棵树不一样,因为如果是同一棵数,同一个元素的位置应该相同,其之前的元素也相同且都已存入。查找完成后,将该结点标记。
代码
#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct TreeNode *Tree;
struct TreeNode //结点
{
int data;
Tree left,right;
bool flag;
};
Tree NewNode(int v) //建立一个新结点
{
Tree t=(Tree)malloc(sizeof(TreeNode)); //分配空间
t->data=v;
t->left=t->right=NULL;
t->flag=0; //标记设为0
return t;
}
Tree Insert(Tree t,int v) //向树中插入元素
{
if(!t)
t=NewNode(v); //如果是空树,建立新结点存v
else
{
if(v>t->data) //插入到右子树中
t->right=Insert(t->right,v);
else if(v<t->data) //插入到左子树中
t->left=Insert(t->left,v);
}
return t;
}
Tree MakeTree(int n) //建树
{
Tree t=NULL; //树初始化为空
for(int i=1;i<=n;i++)
{
int v;
cin>>v;
t=Insert(t,v); //插入
}
return t;
}
bool Check(Tree t,int v) //检查
{
if(t->flag) //被标记了,就肯定是途径的
{
if(v<t->data)
return Check(t->left,v);
else if(v>t->data)
return Check(t->right,v);
else
return 0;
}
else
{
if(v==t->data) //没有被标记,肯定就是最后需要查找的那个
{
t->flag=1;
return 1;
}
else
return 0;
}
}
bool Judge(Tree t,int n)
{
int v;
for(int i=1;i<=n;i++)
{
cin>>v;
if(!Check(t,v)) //判断每一个
{
for(int j=i+1;j<=n;j++) //!!!将剩余的数据读完
cin>>v;
return 0;
}
}
return 1;
}
void ResetTree(Tree t) //清除树的标记
{
if(t->left)
ResetTree(t->left);
if(t->right)
ResetTree(t->right);
t->flag=0;
}
void FreeTree(Tree t) //释放树的空间
{
if(t->left)
FreeTree(t->left);
if(t->right)
FreeTree(t->right);
free(t);
}
int main()
{
int n,l;
while(1)
{
cin>>n;
if(n==0)
return 0;
cin>>l;
Tree t=MakeTree(n);
for(int i=1;i<=l;i++)
{
if(Judge(t,n))
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
ResetTree(t);
}
FreeTree(t);
}
}
方法二
思路
将比较和被比较的树都建立,比较两棵树是否相同
代码
#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct TreeNode *Tree;
struct TreeNode //结点
{
int data;
Tree left,right;
bool flag;
};
Tree NewNode(int v) //建立一个新结点
{
Tree t=(Tree)malloc(sizeof(TreeNode)); //分配空间
t->data=v;
t->left=t->right=NULL;
t->flag=0; //标记设为0
return t;
}
Tree Insert(Tree t,int v) //向树中插入元素
{
if(!t)
t=NewNode(v); //如果是空树,建立新结点存v
else
{
if(v>t->data) //插入到右子树中
t->right=Insert(t->right,v);
else if(v<t->data) //插入到左子树中
t->left=Insert(t->left,v);
}
return t;
}
Tree MakeTree(int n) //建树
{
Tree t=NULL; //树初始化为空
for(int i=1;i<=n;i++)
{
int v;
cin>>v;
t=Insert(t,v); //插入
}
return t;
}
bool Judge(Tree t1,Tree t2)
{
if(t1==NULL&&t2==NULL)
return 1;
if(t1==NULL||t2==NULL)
return 0;
if(t1->data!=t2->data)
return 0;
if(Judge(t1->left,t2->left)&&Judge(t1->right,t2->right))
return 1;
return 0;
}
void FreeTree(Tree t) //释放树的空间
{
if(t->left)
FreeTree(t->left);
if(t->right)
FreeTree(t->right);
free(t);
}
int main()
{
int n,l;
while(1)
{
cin>>n;
if(n==0)
return 0;
cin>>l;
Tree t1=MakeTree(n);
for(int i=1;i<=l;i++)
{
Tree t2=MakeTree(n);
if(Judge(t1,t2))
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
FreeTree(t2);
}
FreeTree(t1);
}
}
方法三
思路
对于两个要比较的序列,先比较首元素大小,再分别比较两个序列大于首元素的和小于首元素的
比如 3124和3412比较 3和3相等, 3124分为{12}3{4} ; 3412分为{12}3{4} 12和12相同,4和4相同,所以两个序列相同
对于3124和3241,3和3相等,3124分为{12}3{4} ; 3214分为{21}3{4} ,按照同样的方法比较12和21,1和2不同,两个序列不同
代码
有点问题,暂时没发现在哪儿。求帮忙看看 orz
#include<iostream>
using namespace std;
int n;
bool judge(int a[],int b[],int l)
{
int ab[11],as[11],bb[11],bs[11];
int posab=0,posas=0,posbb=0,posbs=0;
if(l==0)
return 1;
if(a[1]!=b[1])
return 0;
if(l==1)
return 1;
for(int i=2;i<=l;i++)
{
if(a[i]>a[1])
ab[++posab]=a[i];
else if(a[i]<a[1])
as[++posas]=a[i];
}
for(int i=2;i<=l;i++)
{
if(b[i]>b[1])
bb[++posbb]=b[i];
else if(b[i]<b[1])
bs[++posbs]=b[i];
}
if(posab!=posbb||posas!=posbs)
return 0;
if(judge(ab,bb,posab)&&judge(as,bs,posas))
return 1;
return 0;
}
int main()
{
while(1)
{
cin>>n;
if(n==0)
return 0;
int a[11],b[11];
for(int i=1;i<=n;i++)
cin>>a[i];
int l;
cin>>l;
for(int i=1;i<=l;i++)
{
for(int j=1;j<=n;j++)
cin>>b[j];
if(judge(a,b,n))
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
}
}