数据结构树 —— 编程作业 05 :是否同一棵二叉搜索树
Posted 大彤小忆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构树 —— 编程作业 05 :是否同一棵二叉搜索树相关的知识,希望对你有一定的参考价值。
题目描述: 给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{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):是否同一棵二叉搜索树。
代码实现:
#include<iostream>
using namespace std;
//搜索树表示
typedef struct TreeNode *Tree;
struct TreeNode
{
int v; //用v表示结点的信息
Tree Left, Right; //用链表形式表示树
int flag; //flag为某个结点是否被访问过的标志,用来判别一个序列是否与树一样,如果某个结点未被访问,flag=0,否则flag=1
};
//建新结点(一般为第一个结点)
Tree NewNode(int V)
{
Tree T = (Tree)malloc(sizeof(struct TreeNode));
T->v = V;
T->Left = T->Right = NULL;
T->flag = 0;
return T;
}
//后续结点的插入
Tree Insert(Tree T, int V)
{
if (!T) //T为空
{
T = NewNode(V); //通过NewNode(V)为T构造第一个结点
}
else //T不为空
{
if (V > T->v)
T->Right = Insert(T->Right, V);
else
T->Left = Insert(T->Left, V);
}
return T;
}
//构建搜索树
Tree MakeTree(int N)
{
Tree T;
int V;
cin >> V; //首先读入第一个元素放入V中
T = NewNode(V); //为T构造新结点
for (int i = 1; i < N; i++)
{
cin >> V; //依次读入序列后面的元素
T = Insert(T, V); //读入的后面元素依次插入树T
}
return T;
}
//如何判别(已经访问过的结点要进行标记,使flag=1)
//在树T中按顺序搜索序列中的每个数,如果每次搜索所经过的结点在前面均出现过,则一致;
// 否则如果某次搜索中遇到前面未出现的结点,则不一致。
int check(Tree T, int V)
{
if (T->flag) //某个结点被访问过(因为之前的V == T->v,才使得flag =1)
{
if (V < T->v)
return check(T->Left, V);
else if (V > T->v)
return check(T->Right, V);
else //如果V == T->v,意味着这个序列中有两个元素出现了两次以上,即重复出现,认为不一致
return 0;
}
else //某个结点未被访问过
{
if (V == T->v) //如果未被访问过的结点刚好是所搜索的,使flag=1
{
T->flag = 1;
return 1;
}
else //否则未被访问过的结点不是所搜索的,即遇到前面未出现的结点,使flag=0
return 0;
}
}
int Judge(Tree T, int N)
{
int V, same = 1;
//same:1代表目前还一致,0代表已经不一致
cin >> V;
if (V != T->v) //序列第一个元素与T的根结点不一致
same = 0; //两棵树已经不一致
else
T->flag = 1;
for (int i = 1; i < N; i++)
{
cin >> V;
if ((same) && (!check(T, V)))
same = 0;
}
if (!same)
return 0;
else
return 1;
}
//清除T中各个结点的标记
void ResetT(Tree T)
{
if (T->Left)
ResetT(T->Left);
if (T->Right)
ResetT(T->Right);
T->flag = 0;
}
//释放T的空间
void FreeTree(Tree T)
{
if (T->Left)
FreeTree(T->Left);
if (T->Right)
FreeTree(T->Right);
free(T);
}
int main()
{
Tree T;
int N, L; // N个结点,L个序列
cin >> N;
while (N)
{
cin >> L;
T = MakeTree(N); //根据第一行序列建N个结点的树T
for (int i = 0; i < L; i++) //依据树T分别判别后面的L个序列是否能与T形成同一搜索树并输出结果
{
if (Judge(T, N))
cout << "Yes" << endl;
else
cout << "No" << endl;
ResetT(T); //清除T中的标记flag
}
FreeTree(T);
cin >> N;
}
system("pause");
return 0;
}
测试: 输入样例的测试效果如下图所示。
以上是关于数据结构树 —— 编程作业 05 :是否同一棵二叉搜索树的主要内容,如果未能解决你的问题,请参考以下文章