数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)

这篇具有很好参考价值的文章主要介绍了数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

题意理解

问题

描述

输入样例 

输出样例

求解思路

建两棵二叉树

不建树

建一棵树

搜索树表示

程序框架搭建

如何建搜索树

如何判别

方法

查找函数

判断函数

其他函数


题意理解

给定一个插入序列就可以唯一确定一颗二叉搜索树。

但是,一颗给定的二叉搜索树却可以由多种不同的插入序列得到。

例如,按照序列{2,1,3}和{2,3,1}插入初始为空的二叉搜索树,都得到一样的结果。

数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)

问题

描述

对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。

输入样例 

4 2              第一部分是两个整数:4表示插入二叉搜索树的节点数、2表示要进行比较的序列

3 1 4 2        第二部分是输入的序列                                                    

3 4 1 2        第三部分是后面输入的序列,它们全部都要与第二部分进行对比,判断是否一样

3 2 4 1

2 1

2 1

1 2

0

输出样例

Yes

No

No

 数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)

求解思路

建两棵二叉树

根据两个序列分别建树,再去递归判别两棵树是否一样。

不建树

例如: 

3 1 2 4 对比 3 4 1 2,3都是根结点。

那找出所有比3大的结点和所有比3小的结点,发现:

数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)

很显然,我们能看出他们是同一棵二叉搜索树了。 

再来对比一组:3  1  2  4、3  2  4  1。

 数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)

 这一组序列并不是同一棵二叉搜索树。

建一棵树

根据结点数来建立一棵二叉搜索树T,再来判别一个序列是否与二叉搜索树T一致。

分为三部分:

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

搜索树表示

typedef struct TreeNode* Tree;
struct TreeNode
{
	int v;
	Tree Left, Right;
	int flag;
};

程序框架搭建

int main()
{
    对每组数据
        1.读入N和L
        2.根据第一行序列建树T
        3.依据树T分别判别后面的L个序列是否能与T形成同一搜索树并输出结果。
        return 0;
}

需要设计的主要函数:

  • 读数据建立搜索树T
  • 判别一序列是否与T构成一样的搜索树
int main()
{
	int N, L, i;
	Tree T;
	scanf("%d", &N);
	while (N)
	{
		scanf("%d", &L);
		T = MakeTree(N);
		for (i = 0; i < L; i++)
		{
			if (Judge(T, N))
				printf("Yes\n");
			else
				printf("No\n");
			ResetT(T); /*清除T中的所有标记flag*/
		}
		FreeTree(T);
		scanf("%d", &N);
	}
	return 0;
}

如何建搜索树

Tree MakeTree(int N)
{
	Tree T;
	int i, V;
	scanf("%d", &V);
	T = NewNode(V);
	for (i = 1; i < N; i++)
	{
		scanf("%d", &V);
		T = Insert(T,V);
	}
	return T;
}
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 = NewNode(V);
	else
	{
		if (V > T->v)
			T->Right = Insert(T->Right, V);
		else
			T->Left = Insert(T->Left, V);
	}
	return T;
}

如何判别

 数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)

如何判别序列3  2  4  1是否与树T一致呢? 

方法

在树T中按顺序搜索序列3  2  4  1中的每个数:

  • 如果每次搜索所经过的结点在前面均出现过,则一致
  • 否则(某次搜索中遇到前面未出现过的结点),则不一致

 数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)

查找函数

check函数接受两个参数:一个二叉搜索树T和一个整数V。

函数的返回值为整型。

在二叉搜索树T中查找整数V, 如果找到了,则将该结点的标记flag设为1,并返回1;

如果没有找到,则返回0。

用递归的方式:首先判断当前结点是否被标记,如果被标记,则根据V与当前结点的大小关系,递归地查找左子树或右子树。

如果当前结点未被标记,则判断V是否等于当前结点的值, 如果等于,则将该结点的标记设为1,并返回1;

否则返回0。

int check(Tree T, int V)
{
	if (T->flag)
	{
		if (V < T->v)
		{
			return check(T->Left, V);
		}
		else if (V > T->v)
		{
			return check(T->Right, V);
		}
		else
			return 0;
	}
	else
	{
		if (V == T->v)
		{
			T->flag = 1;
			return 1;
		}
		else
		{
			return 0;
		}
	}
}

判断函数

int Judge(Tree T, int N)
{
	int i, V;
	scanf("%d", &V);
	if (V != T->v)
	{
		return 0;
	}
	else
	{
		T->flag = 1;
	}
	for (i = 1; i < N; i++)
	{
		scanf("%d", &V);
		if (!check(T, V)) 
		return 0;
	}
	return 1;
}

函数有两个参数:一个是指向树的指针T,另一个是整数N。

首先从输入中读取一个整数V,如果V不等于树T的根结点值,则返回0, 表示输入的第一个数与树T不匹配。

如果V等于树T的根结点值,则将根结点的标记flag设置为1, 表示该节点已经被访问过。

接下来,用一个循环来读取剩余的N-1个整数。

对于每个整数V,函数调用check函数来检查树T中是否存在一个结点的值等于V。

如果不存在这样的节点,则返回0,表示输入的整数与树T不匹配。

如果存在这样的节点,则将该节点的标记flag设置为1, 表示该节点已经被访问过。

最后,如果所有的输入整数都能在树T中找到对应的节点,则返回1,表示输入的整数与树T匹配。

但是这段代码是存在bug的,当发现序列中的某个数与T不一致时,返回0程序结束,而不会把后面的数读完了。

那么就会误把后面的数当成下一组序列来看了,导致序列错乱了。

所以,当发现序列中的某个数与T不一致时,必须把序列后面的数都读完。

据此来改进代码:

int Judge(Tree T, int N)

{
	int i, V, flag = 0;

	/*flag:0代表目前还一致,1代表已经不一致*/

	scanf("%d", &V);

	if (V != T->v)flag = 1;
	else T->flag = 1;
	for (i = 1; i < N; i++)
	{
		scanf("%d", &V);
		if ((!flag) && (!check(T,V)))
			flag = 1;
	}
	if (flag) 
		return 0;
	else 
		return 1;
}

输入参数为一个指向二叉树根结点的指针T和一个整数N,表示序列的长度。

函数的返回值为1或0,表示给定的二叉树是否与序列匹配。

首先从输入中读取第一个整数V,表示序列中的第一个元素。

如果V与二叉树根结点的值不相等,则将flag(这里是函数内部的flag标记)标记为1,表示当前已经不一致了;

否则将根节点的flag(这里是结点内的flag标记,表示是否访问过)标记为1,表示已经匹配上了。

再循环读取序列中的剩余元素,每次读取一个整数V。

如果当前已经不一致了(即flag为1),则直接跳过后面的元素。

如果当前还一致,并且当前节点的值等于V,则将当前节点的flag标记为1,表示已经匹配上了;

否则将flag标记为1,表示当前已经不一致了。

循环结束后,如果flag为1,则说明序列与二叉树不匹配,返回0;

否则返回1,表示匹配成功。

其他函数

清除T中各结点的flag标记

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

先递归处理其左子树,再递归处理其右子树, 最后将该结点的flag标记设为0,表示清除标记。 这样,整个二叉树中所有节点的flag标记都被清除了。

释放T的空间

void FreeTree(Tree T) /*释放T的空间*/
{
	if (T->Left)
		FreeTree(T->Left);
	if (T->Right)
		FreeTree(T->Right);
	free(T);
}

end


学习自:MOOC数据结构——陈越、何钦铭文章来源地址https://www.toymoban.com/news/detail-431659.html

到了这里,关于数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 数据结构上机实验——二叉树的实现、二叉树遍历、求二叉树的深度/节点数目/叶节点数目、计算二叉树度为1或2的节点数、判断二叉树是否相似

    数据结构上机实验——二叉树的实现、二叉树遍历、求二叉树的深度/节点数目/叶节点数目、计算二叉树度为1或2的节点数、判断二叉树是否相似

       建立一棵二叉树,试编程实现二叉树的如下基本操作。    1.创建一棵一棵二叉算法。    2.对这棵二叉树进行遍历:先序或中序或后序,分别输出结点的遍历序列。    3.求二叉树的深度/节点数目/叶节点数目。(选做一个)    4.计算二叉树中度为1 的结点数;

    2024年02月06日
    浏览(15)
  • 判断两个IP是否在同一网段(SHELL实现)

    实现代码

    2024年03月19日
    浏览(9)
  • 题解 | #判断两个IP是否属于同一子网# 简单好理解

    题解 | #判断两个IP是否属于同一子网# 简单好理解

    题解 | #合并两个排序的链表# import java.util.*;/* * public class ListNode { * int val; * ListNode next =   题解 | #高精度整数加法# const rl = require(\\\"readline\\\").createInterface({ input: process.stdin   二本电气工程及其自动化投春招 听劝抗压 求指点 怎么修改   题解 | #查找两个字符串a,b中的最长公共子

    2024年03月24日
    浏览(29)
  • 如何判断2台设备是否在同一个局域网?

    如何判断2台设备是否在同一个局域网?

    需要局域网环境debug,但是家里只有一个无线路由器+台式机(有线连接路由器)+开发板(无线连接到路由器),因此好奇台式机和开发板是否是同一局域网? 1.台式机输入ipconfig,获取网络信息。   ip 地址是:192.168.10.2 子网掩码是:255.255.255.0 2.开发板因为是linux 环境,shell 下

    2024年02月11日
    浏览(13)
  • 【华为OD机试】1035 - 判断两个IP是否属于同一子网

    🍂个人博客首页: KJ.JK   🍂专栏介绍: 华为OD机试真题汇总,定期更新华为OD各个时间阶段的机试真题,每日定时更新,本专栏将使用Python语言进行更新解答,包含真题,思路分析,代码参考,欢迎大家订阅学习

    2024年02月02日
    浏览(16)
  • (IP地址的计算)判断两个IP是否归属于同一子网

    目录 前言 判断依据(附示例) 问题          今天在做题的时候做到了IP地址计算这一部分的题目,太久没有看过了,忘得都差不多了,所以就查阅了资料并做了如下笔记,帮助学习理解,同时把这道题的题目与网友分享的做法分享给大家,可以一起做一做,希望能帮助

    2024年02月08日
    浏览(8)
  • 判断两个 IP 地址是否在同一个局域网中

    如何判断两个 IP 地址是否在同一个局域网中, 核心知识点是出于一个网络号, 主要是通过本身ip 与 所处的子网掩码进行 计算处理是否处于同一个局域网中(在 TCP/IP协议规则里面,IP地址与子网掩码做与运算)。

    2024年02月13日
    浏览(12)
  • 判断两个IP地址(ipv4)是否在同一个网段

    判断两个IP地址(ipv4)是否在同一个网段

    我们通常会遇到的ip地址是这样的: ip地址:192.168.227.205 子网掩码:255.255.255.0 ip地址:192.168.226.202 子网掩码:255.255.255.0 下面我们把子网掩码换成255.255.252.0再来判断下: ip地址:192.168.227.205 子网掩码:255.255.252.0 ip地址:192.168.226.202 子网掩码:255.255.252.0 结论: 所以判断两

    2023年04月08日
    浏览(9)
  • 【华为机试真题详解JAVA实现】—判断两个IP是否属于同一子网

    【华为机试真题详解JAVA实现】—判断两个IP是否属于同一子网

        目录 一、题目描述 二、解题代码 IP地址是由4个0-255之间的整数构成的,用\\\".\\\"符号相连。 二进制的IP地址格式有32位,例如:10000011,01101011,00000011,00011000;每八位用十进制表示就是131.107.3.24 子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。 子网

    2023年04月09日
    浏览(23)
  • 怎么看同一个路由器有几个人在用(判断是否被蹭网)

    棱镜门事件折射出了很多令用户对隐私的担忧,其中这种现象也很常见,不如我们常用的路由器无线网络经常就会遭遇被他人入侵蹭网。今天本文不与大家讨论什么棱镜门事件,而是讨论下很多路由器用户比较关系的路由器有几个人在用的问题。有兴趣的朋友不妨阅了解下。

    2024年02月06日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包