是否同一棵二叉搜索树
题目描述
给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{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
解题思路
- 搜索二叉树:二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势;所以应用十分广泛,例如在文件系统和数据库系统一般会采用这种数据结构进行高效率的排序与检索操作。
- 根据搜索二叉树的定义,首先要创建一颗二叉树。方法为:每增加一个数据都需要从根结点开始与增添的数据进行比较,如果比根节点数据大则继续和右子树比较,反之则与左子树继续进行比较。直到当前节点为空时将该数据存储在当前节点。
- 创建完首棵二叉树Root之后循环输入L个需要检查的序列,每一次循环对当前序列创建一个新的二叉树Test,判断Test与Root是否为同一棵二叉树,如果为同一棵二叉树则输出Yes,反之则输出No。
#include<iostream>
using namespace std;
// 结点的定义
typedef struct Node {
int data;
struct Node* left;
struct Node* right;
}Tree, * TreeNode;
// 向搜索二叉树中插入数据
void CreatTree(TreeNode& Root, int data) {
if (Root == NULL) {
Root = new Tree;
Root->data = data;
Root->left = Root->right = NULL;
}
else
{
if (data > Root->data) {
CreatTree(Root->right, data);
}
else {
CreatTree(Root->left, data);
}
}
}
// 闯将搜索二叉树
void BulidTree(TreeNode& Root, int n) {
int i;
Root = new Node;
cin >> Root->data;
Root->left = Root->right = NULL;
for (i = 1; i < n; i++) {
int t;
cin >> t;
CreatTree(Root, t);
}
}
// 判断是否是同一棵树
bool Judge(TreeNode Root, TreeNode Test) {
if (Root == NULL && Test == NULL)
return true;
if (Root != NULL && Test == NULL)
return false;
if (Root == NULL && Test != NULL)
return false;
if (Root->data != Test->data)
return false;
return Judge(Root->left, Test->left) && Judge(Root->right, Test->right);
}
int main() {
int n, l;
TreeNode Root;
cin >> n;
while (n) {
cin >> l;
BulidTree(Root, n);
while (l--) {
int flag = 1;
TreeNode Test;
BulidTree(Test, n);
if (Judge(Root, Test) == 0) {
flag = 0;
}
free(Test); // 每次判断结束释放检测二叉树的根结点
if (flag == 1) {
cout << "Yes" << endl;
}
else {
cout << "No" << endl;
}
}
cin >> n;
free(Root); // 每组数据测试完之后释放比较二叉树的根结点。
}
return 0;
}