7-4 是否同一棵二叉搜索树(25分)
题目描述
给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列 {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
题目链接
7-4 是否同一棵二叉搜索树
解题思路
本题的解题思路主要由两部分组成;
- 二叉搜索树的创建;
- 判断两棵树是否是相同的;
二叉搜索树的创建
这里可以参考 二叉搜索树的C实现 这篇文章,是关于二叉搜索树的操作集的。代码如下:
BinTree *Insert( BinTree *BST, int data ) {
if ( BST == NULL ) {
BST = ( BinTree *) malloc( sizeof(BinTree) );
BST->val = data;
BST->left = BST->right = NULL;
}
else if ( BST->val > data ) {
BST->left = Insert( BST->left, data );
}
else if ( BST->val < data ){
BST->right = Insert( BST->right, data );
}
return BST;
}
判断两棵树是否是相同的
与判断树的同构相比要简单很多,分三种情况讨论即可:
- 两棵树全是空树,直接返回 true
- 一棵空树另一棵树非空,直接返回false
- 两棵树均非空,判断根结点值是否相等,不相等直接返回 false;反之递归左右子树
bool isSame(BinTree *BST, BinTree *temp ) {
if ( BST == NULL && temp == NULL ) {
return true;
}
else if ( BST == NULL || temp == NULL ) {
return false;
}
return ( BST->val == temp->val ) && isSame(BST->left, temp->left) && isSame(BST->right, temp->right);
}
全部代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
} BinTree;
BinTree *Insert( BinTree *BST, int data ) {
if ( BST == NULL ) {
BST = ( BinTree *) malloc( sizeof(BinTree) );
BST->val = data;
BST->left = BST->right = NULL;
}
else if ( BST->val > data ) {
BST->left = Insert( BST->left, data );
}
else if ( BST->val < data ){
BST->right = Insert( BST->right, data );
}
return BST;
}
bool isSame(BinTree *BST, BinTree *temp ) {
if ( BST == NULL && temp == NULL ) {
return true;
}
else if ( BST == NULL || temp == NULL ) {
return false;
}
return ( BST->val == temp->val ) && isSame(BST->left, temp->left) && isSame(BST->right, temp->right);
}
void DestroyTree( BinTree *BST ) {
if ( BST != NULL ) {
DestroyTree( BST->left );
DestroyTree( BST->right );
free(BST);
}
}
int main()
{
int N, L;
scanf("%d %d", &N, &L);
while ( N != 0 ) {
BinTree *BST = NULL, *temp = NULL;
int number;
for ( int i = 0; i < N; i ++ ) {
scanf("%d", &number);
BST = Insert(BST, number);
}
while ( L -- ) {
for ( int i = 0; i < N; i ++ ) {
scanf("%d", &number);
temp = Insert(temp, number);
}
if (isSame(BST, temp)) {
printf("Yes\n");
}
else {
printf("No\n");
}
DestroyTree(temp);
temp = NULL;
}
DestroyTree(BST);
scanf("%d", &N);
if ( N != 0 ) {
scanf("%d", &L);
}
}
return 0;
}