04-树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
先建立搜索树,然后对要检查序列 squ 里的每一个数进行查找(设目前找的是第 i 个数),并且记录下查找的路径 through。
若 through 中所有的数都能在 squ[i] 之前的数中被找到,那么就继续检查
当 squ 中所有数都被查完且满足上面的条件就是同一棵搜索树
#include <iostream>
#define Tree int
#define MAX_SIZE 10
typedef struct _tree_node
{
Tree data;
Tree Left;
Tree Right;
} Tree_node;
void build_tree(int N, Tree_node BTree[], Tree root);
bool is_sam_tree(Tree_node [], Tree [], int N, Tree root);
bool check_squ(Tree[], Tree[], int , int );
int main()
{
int N, L,is_first_time = 1;
Tree root = 0;
std::cin >> N >> L;
while (N != 0)
{
Tree_node BTree[MAX_SIZE];
std::cin >> BTree[root].data;
BTree[root].Left = BTree[root].Right = -1;
build_tree(N, BTree, root);
//读入序列,判断是否为同一搜索树,然后输出
bool flag;
for (int i = 0; i < L; i++)
{
Tree squ[MAX_SIZE];
for (int i = 0; i < N; i++)
std::cin >> squ[i];
flag = is_sam_tree(BTree, squ, N, root);//判断
//按格式输出
if (is_first_time)
is_first_time = 0;
else
std::cout << std::endl;
if (flag)
std::cout << "Yes";
else
std::cout << "No";
//===========
}
//==========================
std::cin >> N;
if (N != 0) std::cin >> L;
}
return 0;
}
void build_tree(int N, Tree_node BTree[], Tree root)
{
Tree pos;
for (int i = 1; i < N; i++)
{
pos = root;
std::cin >> BTree[i].data;
BTree[i].Left = BTree[i].Right = -1;
while (1)
{
if (BTree[pos].data < BTree[i].data)
{
if (BTree[pos].Right != -1)
pos = BTree[pos].Right;
else
{
BTree[pos].Right = i;
break;
}
}
else
{
if (BTree[pos].Left != -1)
pos = BTree[pos].Left;
else
{
BTree[pos].Left = i;
break;
}
}
}
}
}
bool is_sam_tree(Tree_node BTree[], Tree squ[], int N, Tree root)
{
Tree pos;
int k;
for (int i = 0; i < N; i++)
{
k = 0;
pos = root;
Tree through[MAX_SIZE];
while (pos != -1)
{
through[k++] = BTree[pos].data;
if (BTree[pos].data == squ[i]){
break;
}
else if(BTree[pos].data < squ[i]){
pos = BTree[pos].Right;
}
else {
pos = BTree[pos].Left;
}
}
if (!check_squ(through, squ, k, i+1)) //查找穿过路径的所有节点是否全部存在于squ的前i+1个节点中, k有做++所以无需+1
return false;
}
return true;
}
bool check_squ(Tree through[], Tree squ[], int how_long_through, int how_long_squ)
{
bool flag;
for (int i = 0; i < how_long_through; i++)
{
flag = false;
for (int j = 0; j < how_long_squ; j++)
{
if (through[i] == squ[j]) {
flag = true;
break;
}
}
if (flag == false)
return false;
}
return true;
}