小白专场—是否同一棵二叉搜索树
给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。
输入格式:
输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列。最后L行,每行给出N个插入的元素,属于L个需要检查的序列。
简单起见,我们保证每个插入序列都是1到N的一个排列。当读到N为0时,标志输入结束,这组数据不要处理。
输出格式:
对每一组需要检查的序列,如果其生成的二叉搜索树跟对应的初始序列生成的一样,输出“Yes”,否则输出“No”。
求解思路
两个序列是否对应相同搜索树的判别
- 1、分别建两棵搜索树的判别方法
- 项目根据两个序列分别建树,再判别树是否一样* 根据两个序列分别建树,再判别树是否一样
- 2、不建树的判别方法
- 3、建立一棵树,再判别其他序列是否与该树一致
首先是根据第一种思路:
1.建立两棵树对比其元素
#include<iostream>
#include<stdlib.h>
using namespace std;
#define elemtype int
typedef struct BiNode
{
int data;
struct BiNode *left;
struct BiNode *right;
}BiNode,*BiTree;
void Insert(BiTree &tree,BiTree &btp)
{
if (tree == NULL)
return;
if (btp->data > tree->data)
{
if (tree->right == NULL)
tree->right = btp;
else
Insert(tree->right, btp);
}
if (btp->data < tree->data)
{
if (tree->left == NULL)
tree->left = btp;
else
Insert(tree->left,btp);
}
}
void SearchTree(BiTree& tree,BiTree &btp)
{
if (tree == NULL)
tree = btp;
else
Insert(tree,btp);
}
void CreateOrderBinaryTree(BiTree &tree, int n)
{
for (int i = 0; i < n; i++)
{
int idata;
cin >> idata; //读入树中的每一个结点数据
BiTree btp;
btp = (BiTree)malloc(sizeof(BiNode));
btp->data = idata;
btp->left = NULL;
btp->right = NULL;
SearchTree(tree,btp);
}
}
//判断两棵树是否相同
bool Judge(BiTree tree,BiTree tmptree)
{
if (tree == NULL && tmptree == NULL)
return true;
else if ((tree != NULL&&tmptree == NULL) || (tree == NULL&&tmptree != NULL))
return false;
else if ((tree!=NULL&&tmptree!=NULL) && (tree->data != tmptree->data))
return false;
return Judge(tree->left,tmptree->left) && Judge(tree->right,tmptree->right);
}
//释放空间
void freedom(BiTree &pRoot)
{
if (pRoot->left == NULL&&pRoot->right)
free(pRoot);
else if (pRoot->left != NULL)
freedom(pRoot->left);
else if (pRoot->right != NULL)
freedom(pRoot->right);
}
int main()
{
int N, L;//n表示每一棵有几个结点,l表示有几颗树要与该树比较
cin >> N;
while (N)
{
cin >> L;
BiTree tree=NULL;
CreateOrderBinaryTree(tree,N);
for (int i = 0; i < L; i++)
{
BiTree tmptree = NULL;
CreateOrderBinaryTree(tmptree, N);
bool issame=Judge(tree,tmptree);
if (issame == true)
cout << "Yes" << endl;
else
cout << "No" << endl;
freedom(tmptree); //不要忘记释放空间
}
freedom(tree);
cin >> N; //读入下一个数据,如果输入0,程序结束
}
}
之后根据第三种思路
2.建立一棵树,再判别其他序列是否与该树一致
先讲程序框架搭建
int main()
{ 对每组数据
读入N和L
根据第一行序列建树T
依据树T分别判别后面的L个序列是否能与T形成同一搜索树并输出结果
return 0;
}
需要设计的主要函数:
- 读数据建搜索树T
- 判别一序列是否与T构成一样的搜索树
如何判别
如何判别序列3 2 4 1是否 与树T一致?
方法:在树T中按顺序搜索序列3 2 4 1中的每个数
- 如果每次搜索所经过的结点在前面均出现过,则一致
- 否则(某次搜索中遇到前面未出现的结点),则不一致
#include<iostream>
#include<stdlib.h>
using namespace std;
#define Elemtype int
typedef struct BiNode
{
Elemtype data;
int flag; //0:还没被访问过,1:已经访问过了
struct BiNode *left;
struct BiNode *right;
}BiNode,*BiTree;
void Searchtree(BiTree &tree, BiTree &btp)
{
if (tree == NULL)
return;
if (btp->data > tree->data)
{
if (tree->right == NULL)
tree->right = btp;
else
Searchtree(tree->right, btp);
}
else if (btp->data < tree->data)
{
if (tree->left == NULL)
tree->left = btp;
else
Searchtree(tree->left, btp);
}
}
void Insert(BiTree &tree,BiTree &btp)
{
if (tree == NULL)
tree = btp;
else
Searchtree(tree,btp);
}
void CreateOrderBinaryTree(BiTree &tree, int n)
{
for (int i = 0; i < n; i++)
{
int da;
cin >> da;
BiTree btp = (BiTree)malloc(sizeof(BiNode));
btp->data = da;
btp->left = btp->right = NULL;
btp->flag=0;
Insert(tree,btp);
}
}
bool check(BiTree tree, int da)
{
if (tree->flag == 0)
{
if (tree->data == da)
{
tree->flag = 1; //将访问过的结点标志设为1
return true;
}
else
return false;
}
else
{
if (da > tree->data)
check(tree->right, da);
else if (da < tree->data)
check(tree->left, da);
else
return false;
}
}
bool Judge(BiTree tree,int n)
{
int da,mark = 0; //mark:0代表目前还一致,1代表已经不一致
cin >> da;
if (tree->data != da)
mark = 1;
else
tree->flag = 1; //将访问过的结点标志设为1
//每次循环判断访问该数据的路径上有没有没访问过的数据,有,两树不一致
for (int i = 1; i < n; i++)
{
cin >> da;
//当发现序列中的某个数与T不一致时,必须把序列后面的数都读完!
if ((mark == 0) && (check(tree, da)==false))
mark = 1;
}
if (mark == 0)
return true;
else
return false;
}
int main()
{
int N, L;
cin >> N;
while (N)
{
cin >> L;
BiTree tree=NULL;
CreateOrderBinaryTree(tree, N);
for (int i = 0; i < L; i++) //每次循环判断一棵树
{
bool issame = Judge(tree, N);
if (issame==true)
cout << "Yes" << endl;
else
cout << "No" << endl;
}
cin >> N; //读入下一组数据,为0结束函数
}
return 0;
}