您的位置:首页 > 其它

04-树4 是否同一棵二叉搜索树

2017-03-31 23:59 579 查看
给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。

输入格式:

输入包含若干组测试数据。每组数据的第1行给出两个正整数NN (\le 10≤10)和LL,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出NN个以空格分隔的正整数,作为初始插入序列。最后LL行,每行给出NN个插入的元素,属于LL个需要检查的序列。

简单起见,我们保证每个插入序列都是1到NN的一个排列。当读到NN为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

求解思路
两个序列是否对应相同搜索树的判别
1.分别建两棵搜索树的判别方法
2.不建树的判别方法
3. 建一棵树,再判别其他序列是否与该树一致

求解思路
1. 搜索树表示
2. 建搜索树T
3. 判别一序列是否与搜索树T一致

/*!
* \file 04-树4 是否同一棵二叉搜索树.cpp
*
* \author ranjiewen
* \date 三月 2017
*
*
*/

//两个序列是否对应相同搜索树的判别
//1.分别建两棵搜索树的判别方法
//2.不建树的判别方法
//3. 建一棵树,再判别其他序列是否与该树一致

#include <stdio.h>
#include <stdlib.h>
typedef int Status;  //函数类型
typedef int ElementType;

typedef struct TreeNode* BSTree;
struct TreeNode
{
ElementType Data;
BSTree Left;
BSTree Right;
int Flag;   //被访问为1,否则0
};

BSTree NewNode(ElementType data);
BSTree Insert(BSTree T, ElementType data);
BSTree MakeTree(int N);
bool Check(BSTree T,ElementType data);
int Judge(BSTree T);
void ResetT(BSTree T);
void FreeT(BSTree T);

BSTree NewNode(ElementType data)
{
BSTree root = (BSTree)malloc(sizeof(struct TreeNode));
root->Data = data;
root->Left = NULL;
root->Right = NULL;
root->Flag = 0;
return root;
}

BSTree Insert(BSTree root, ElementType data)
{
if (root==NULL)
{
root = NewNode(data);
}
else
{
if (root->Data < data)
{
root->Right = Insert(root->Right, data);
}
else
{
root->Left = Insert(root->Left, data);
}
}
return root;
}

BSTree MakeTree(int N)
{
BSTree T;
ElementType data;
scanf("%d", &data);
T = NewNode(data);
for (int i = 1; i < N; i++)
{
scanf("%d", &data);
T = Insert(T, data);
}
return T;
}

//将另一棵树的结点依次在一颗二叉树上搜索,找到后标记;当搜索过程中有未被标记的结点,说明两棵树不一样
bool Check(BSTree T, ElementType data)
{
if (T->Flag)
{
if (data<T->Data)
{
return Check(T->Left, data);
}
else
{
return Check(T->Right, data);
}
}
else
{
if (data==T->Data)
{
T->Flag = 1;
return true;
}
else
{
return false; //结点不一致
}
}
}

int Judge(BSTree T, int N)
{
ElementType data;
int flag = 0; //0代表目前乃一致,1代表已经不一致
scanf("%d", &data);
if (data!=T->Data) //判断根结点是否一致
{
flag = 1; //不一致的情况下也要把后面的结点输入后才做判断
}
else T->Flag = 1;
for (int i = 1; i < N; i++)
{
scanf("%d", &data);
if ((!flag)&&(!Check(T,data)))
{
flag = 1;
}
}
if (flag)
{
return 0;
}
else
return 1;
}

void ResetT(BSTree T) //清除T中各结点的flag标记
{
if (T->Left)
{
ResetT(T->Left);
}
if (T->Right)
{
ResetT(T->Right);
}
T->Flag = 0;
}

void FreeT(BSTree T) //释放T的空间
{
if (T->Left)
{
FreeT(T->Left);
}
if (T->Right)
{
FreeT(T->Right);
}
free(T);
}

int main()
{
int N;
int L;
BSTree T;
scanf("%d", &N);
while (N)  //可以多次输入测试
{
scanf("%d", &L); //需要检查的序列个数
T = MakeTree(N); //输入N个元素创建树
for (int i = 0; i < L;i++) //对每个序列操作
{
if (Judge(T, N)) //依次输入N个元素,每个元素都进行标记判断
{
printf("Yes\n");
}
else
{
printf("No\n");
}
ResetT(T);
}
FreeT(T);
scanf("%d", &N);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: