04-树4 是否同一棵二叉搜索树(浙大数据结构PTA习题)

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

鸣谢青岛大学周强老师补充测试数据!

代码长度限制:16 KB        时间限制:400 ms        内存限制:64 MB

题目解析:

关键点1:构建二叉搜索树,主要考察向二叉搜索树中插入元素

        递归插入思想,(1)插入元素的数值小于根结点数值,则向根结点左子树中插入;(2)插入元素的数值大于根结点的数值,则向根结点右子树中插入;

关键点2:比较两棵二叉搜索树是否相同

        递归比较思想,(1)若两棵二叉搜索树均为空,则视为相同的两棵二叉搜索树;(2)若两棵二叉搜索树在根结点相同的情况下,左子树和右子树分别对应相同,则视为相同的两棵二叉搜索树;

参考代码:

# include<stdio.h>
# include<stdlib.h>
# include<stdbool.h>

// 树结点结构 
typedef struct TreeNode* Tree;
struct TreeNode{
	int data;
	Tree left;
	Tree right;
};

Tree InsertTree(Tree tree, int data);
bool IsSameTree(Tree tree1, Tree tree2);
void Game(int N,int L);
void FreeTree(Tree tree);

int main(){
	int N,L;
	scanf("%d",&N);
	// N为0表示输入结束 
	while(N!=0){
		scanf("%d",&L);
		// 一组检查的结果输出 
		Game(N,L);
		scanf("%d",&N);
	}
	return 0;
	
}

// 一组检查 
void Game(int N,int L){
	// 创建一个初始树
	Tree tree = NULL;
	// 向初始树中插入元素
	int i,j,data;
	for(i=0;i<N;i++){
		scanf("%d",&data);
		tree = InsertTree(tree,data);
	}
	// 接收需要检查的序列
	for(i=0;i<L;i++){
		Tree tmp = NULL;
		// 插入元素 
		for(j=0;j<N;j++){
			scanf("%d",&data); 
			tmp = InsertTree(tmp,data);
		}
		// 判读是否是同一棵树并输出结果
		if(IsSameTree(tree,tmp))printf("Yes\n");
		else printf("No\n"); 
		// 检查完毕后释放 
		FreeTree(tmp); 
	} 
	// 释放初始树
	FreeTree(tree); 
	return;
} 


// 二叉搜索树的插入
Tree InsertTree(Tree tree, int data){
	if(tree==NULL){
		// 如果为空树,则创建根结点
		tree = (Tree)malloc(sizeof(struct TreeNode));
		tree->data = data;
		tree->left = tree->right = NULL; 
	}else{
		// 递归插入
		if(data<tree->data){
			// 插入左子树
			tree->left = InsertTree(tree->left,data); 
		}else if(data>tree->data){
			// 插入右子树
			tree->right = InsertTree(tree->right,data); 
		} 
	}
	return tree;
} 

// 判断是否是同一棵树
bool IsSameTree(Tree tree1, Tree tree2){
	// 如果根结点都为空,则是一棵树
	if(tree1==NULL && tree2==NULL)return true;
	// 如果一个根结点为空,另一个不为空,则肯定不是
	if(tree1==NULL && tree2 || tree1 && tree2==NULL)return false;
	// 如果根结点不同,则肯定不是
	if(tree1->data != tree2->data)return false;
	// 递归判读其左子树与右子树是否是同一棵树
	if(IsSameTree(tree1->left,tree2->left) && IsSameTree(tree1->right,tree2->right))return true;
	else return false; 
} 

// 递归释放树 
void FreeTree(Tree tree){
	if(tree->left)FreeTree(tree->left);
	if(tree->right)FreeTree(tree->right);
	free(tree);
} 

运行结果:

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值