给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{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
首先我们先大致理解一下题意:
N是二叉搜索树的节点个数,L是需要与初始序列作比较的序列个数。我们需要根据序列构造L二叉搜索树,并分别与检验二叉树(姑且这样称呼初始序列构成的BST吧)对比,判断是否为同一棵二叉搜索树。
设计的主要操作清楚了:插入数据,构建BST;比较两棵BST是否相同;
如何构建一棵BST呢?
我们需要了解二叉搜索树(BST)的性质:
- 每一个节点的值都要小于其左侧子树中任何值;
- 每一个节点的值都要大于其右侧子树中任何值;
利用递归可以轻松解决这个问题,将要插入的值与当前节点数据data进行比较,大于data递归到右子树,反之,递归到左子树。下面附上参考代码:
Node Insert(Node T,int x)
{
if(!T) //这里要判断T是否为空树,若为空,x就是头结点的data;
{
T=(Node)malloc(sizeof(struct TreeNode));
T->data=x;
T->left=T->right=NULL;
}
else if(x>T->data) T->right=Insert(T->right,x);
else if(x<T->data) T->left=Insert(T->left,x);
return T;
}
二叉搜索树构建好了,那就要和检验二叉树进行比较了:
同样,我们继续采用递归的思想去解决这个问题。这里需要分析的情况不多,直接上代码看看吧
int judge(Node T1,Node T2)
{
if(!T1&&!T2)//若两棵树都是空树,必然是相同的
return 1;
else if((!T1&&T2)||(T1&&!T2)) return 0;//其一为空,则必然不同。
else if(T1->data!=T2->data) return 0; //二者不为空,比较头结点的值,头结点的值不同,就没有比
// 下去的必要了
else return (judge(T1->left,T2->left)&&judge(T1->right,T2->right));//头结点相同,就递归
//到左右子树中去,逐一比较
}
小白啥也不懂ww,写个博客巩固一下,欢迎大家批评建议!!谢谢~
最后附上完整代码
#include<stdlib.h>
#include<stdio.h>
typedef struct TreeNode* Node;
struct TreeNode
{
int data;
Node left;
Node right;
};
Node Insert(Node T,int x);//插入节点,创建树
int judge(Node T1,Node T2);//比较两棵树是否相同
Node Insert(Node T,int x)
{
if(!T)
{
T=(Node)malloc(sizeof(struct TreeNode));
T->data=x;
T->left=T->right=NULL;
}
else if(x>T->data) T->right=Insert(T->right,x);
else if(x<T->data) T->left=Insert(T->left,x);
return T;
}
int judge(Node T1,Node T2)
{
if(!T1&&!T2)
return 1;
else if((!T1&&T2)||(T1&&!T2)) return 0;
else if(T1->data!=T2->data) return 0;
else return (judge(T1->left,T2->left)&&judge(T1->right,T2->right));
}
int main()
{
int n,l,a;
Node BT,T;
scanf("%d %d",&n,&l);
while(n) //n==0时不做处理
{
BT=NULL;
for(int i=0;i<n;i++)//循环一:由初始序列构建二叉树
{
scanf("%d",&a);
BT=Insert(BT,a);
}
for(int i=0;i<l;i++)//循环二:构建 L个 二叉搜索树
{
T=NULL;
for(int j=0;j<n;j++)
{
scanf("%d",&a);
T=Insert(T,a);
}
if(judge(BT,T)) printf("Yes\n");
else printf("No\n");
}
scanf("%d %d",&n,&l);//当n为0的时候,标志输入结束,别漏了!不然会超时的
}
return 0;
}