【C语音 || 数据结构】二叉树--堆

文章目录

    • 前言
        • 1.1 二叉树的概念
        • 1.2 满二叉树和完美二叉树
        • 1.3 堆的概念
        • 1.4 堆的性质
        • 1.4 堆的实现
          • 1.4.1堆的向上调整算法
          • 1.4.1堆的向下调整算法
          • 1.4.1堆的接口实现
          • 1.4.1.1堆的初始化
          • 1.4.1.2堆的销毁
          • 1.4.1.3堆的插入
          • 1.4.1.4堆的删除
          • 1.4.1.4堆的判空
          • 1.4.1.4 获取堆的数据个数

前言

二叉树是一种重要的数据结构,其中每个节点最多有两个子节点:左子节点和右子节点。它常用于实现搜索算法、排序算法、数据存储和图形表示等。二叉树具有递归性,可以通过遍历算法(如前序、中序、后序和层次遍历)来访问其节点。学习和理解二叉树对于掌握更复杂的数据结构和算法至关重要。

1.1 二叉树的概念

二叉树(Binary Tree)是一种特殊的树形数据结构,它的每个节点最多有两个子节点,通常被称为左子节点和右子节点,二叉树的子树有左右之分,其次序不能任意颠倒。

  1. 根节点(Root Node):二叉树的起始节点,它没有父节点,但可能有左子节点和右子节点。
  2. 父节点(Parent Node):对于每个节点(除根节点之外的节点),都有父节点,是一个具有子节点的节点。
  3. 左子节点(Left Child):对于每个节点,其左下方的节点称为其左子节点。
  4. 右子节点(Right Child):对于每个节点,其右下方的节点称为其右子节点。
  5. 叶子节点(Leaf Node):没有子节点的节点称为叶子节点。
  6. 非叶子节点(Non-Leaf Node):除了叶子节点以外的节点都称为非叶子节点。
  7. (Degree):节点的度是指该节点的子节点数量。在二叉树中,节点的度最大为2。
  8. 深度(Depth):从根节点到最远叶子节点的最长路径上的节点数称为二叉树的深度。
  9. 高度(Height):对于任意节点n,n的高度为从n到一片树叶的最长路径上的节点数。所有树叶的高度为0,根节点的高度就是树的高度。
1.2 满二叉树和完美二叉树

满二叉树(Full Binary Tree):除了叶子节点外,每一个节点都有左右两个子节点的二叉树称为满二叉树。

完全二叉树(Complete BinaryTree):完全二叉树从根结点到倒数第二层满足完美二叉树,最后一层可以不完全填充,其叶子结点必须靠左对齐,且不能有短,最后一层最少可以只有一个。

这不是一个完美二叉树
在这里插入图片描述

1.3 堆的概念

(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵 完全二叉树的 数组对象。 堆是非线性数据结构,相当于一维数组,有两个直接后继。

  • 大堆:父节点一定比子节点大,但是兄弟节点之间,不存在大小关系,堆的根节点是整个堆中最大的数
  • 小堆:父节点一定比子节点小,但是兄弟节点之间,不存在大小关系,堆的根节点是整个堆中最小的数

堆的父亲节点的下标和子节点的下标可以进行相互运算:

  • Parent = (Chlid - 1) / 2
  • Chlid = Parent / 2 - 1
1.4 堆的性质
  • 完美二叉树构成。

大堆:
在这里插入图片描述
小堆:
在这里插入图片描述

1.4 堆的实现
1.4.1堆的向上调整算法

给定一个数组,且这个堆是一个小堆,逻辑上看作是一种完美二叉树,需要传两个参数,一个数组,一个就是插入位置的节点在数组中的下标

  • 在数组的最后插入数据,开始进行向上调整算法。
  • 如果这个节点小于他的父亲节点,那就进行交换。
  • 如果这个节点大于他的父亲节点,那就结束向上调整。

这里给一组数据进行交换

int a[] = {10,15,56,25,30,70,5};

在这里插入图片描述
堆的向上调整算法代码实现:

void Swap(HPDataType* x,HPDataType* y)
{
	HPDataType tmp = *x;
	*x = *y;
	*y = tmp;
}
void AdjustUp(HPDataType* a, int child)
{
	int Parent = (child- 1) / 2;
	while (child> 0)
	{
		if (a[Parent] > a[child])
		{
			Swap(&a[Parent], &a[child]);
			child = Parent;
			Parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}
1.4.1堆的向下调整算法

给定一个数组,且这个堆是一个小堆,逻辑上看作是一种完美二叉树。然后我们从根节点开始向下调整,向下调整算法有一个前提:左右子树必须是一个堆,才能进行调整。然后计算出这个根节点的两个孩子节点,进行比较,哪个小,让其与根节点进行比较。这里需要传三个参数,第一个数组,第二个是数组的个数,第三个是根节点的下标

  • 如果根节点大于孩子节点,那就进行交换。
  • 如果根节点小于孩子节点,就停止交换。

这里给一组数据进行交换

int a[]= {}

在这里插入图片描述
堆的向下调整算法代码实现:

void Swap(HPDataType* x,HPDataType* y)
{
	HPDataType tmp = *x;
	*x = *y;
	*y = tmp;
}
void AdjustDown(HPDataType* a, int n, int Parent)
{
	// 这里可以使用假设法
	int child = Parent * 2 + 1;
	while (child < n)
	{
		// 假设法这个位置需要进行判断是否是小的哪个孩子,不是则需要进行更新
		if (a[child] > a[child + 1] && child + 1 < n)
		{
			child += 1;
		}
		if (a[Parent] > a[child])
		{
			Swap(&a[Parent], &a[child]);
			Parent = child;
			child = Parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
1.4.1堆的接口实现
  • 堆的初始化(HeapInit):用于初始化堆结构,为堆的后续操作做好准备。
  • 堆的销毁(HeapDestroy):释放堆占用的资源,通常涉及删除堆中的所有元素和释放内存。
  • 堆的插入(HeapPush):向堆中插入一个新元素,并保持堆的性质(大堆或小堆)。
  • 堆的删除(HeapPop):删除堆顶数据,将堆顶数据和堆尾数据进行交换,并保持堆的性质(大堆或小堆)。
  • 获取堆顶数据(HeapTop):获取堆顶数据。
  • 堆的判空(HeapEmpty):判断堆是否是空。
  • 堆的数据个数(HeapSize):计算堆中的数据个数。
1.4.1.1堆的初始化

对于堆的这个结构体来说,可以给_a开空间,也可以不开,一会儿进行push的时候,会进行判断,所以就可以制空,以防止成为野指针。对于size,可以给-1,这样就刚刚好和下标对上了。

typedef int HPDataType;
typedef struct Heap
{
	HPDataType* _a;
	int _size;    // 堆顶的下一个位置的下标
	int _capacity;// 堆的空间
}Heap;
// 堆的初始化
void HeapInit(Heap* hp)
{
	assert(hp);

	hp->_a = NULL;
	hp->_capacity = hp->_size = 0;
}

1.4.1.2堆的销毁
void HeapDestroy(Heap* php)
{
	assert(php);
	free(php->_a);
	php->_a = NULL;
	php->_size = php->_capacity = 0;
}
1.4.1.3堆的插入

这里插入数据,需要插入到这个数组的最后一个位置,然后进行向上调整算法,让他始终保持这个小堆(大堆)。

void HeapPush(Heap* php,HPDataType x)
{
	assert(php);
	if (php->_capacity == php->_size)
	{
		int newcapacity = php->_capacity == 0 ? 4 : php->_capacity * 2;
		HPDataType* new_a = (HPDataType*)realloc(php->_a,newcapacity*sizeof(HPDataType));
		if (new_a == NULL)
		{
			perror("HeapPush()::realloc() fail!!");
			return;
		}
		php->_capacity = newcapacity ;
		php->_a = new_a;
	}
	php->_a[php->_size++] = x;
	AdjustUp(php->_a, hp->_size - 1);
}
1.4.1.4堆的删除

需要将堆中最后一个节点于整个堆的根节点进行交换,交换完成之后,直接删除最后一个下标的位置,在进行向下调整。

void HeapPop(Heap* php)
{
	assert(php && php->_size > 0);
	Swap(&php->_a[0],&php->_a[php->_size - 1]);
	php->_size--;
	AdjustDown(php->_a, php->_size, 0);
}
1.4.1.4堆的判空

因为结构体中的size就是用来记录堆的数据个数的,所以可以直接判断这个数是否等于0。

int HeapEmpty(Heap* php)
{
	assert(php);
	 return php->_size == 0;
}
1.4.1.4 获取堆的数据个数

结构体中的size就是用来计数的,所以会方便很多

void HeapSize(Heap* php)
{
	assert(php);
	return php->_size;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/703429.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

轻松玩转新商业模式:工会排队!

在当今数字化时代&#xff0c;互联网的蓬勃发展不仅重塑了商业模式&#xff0c;也深刻改变了消费者的购物习惯。传统的实体零售店面与在线销售平台正面临着巨大的市场挑战。然而&#xff0c;正是这些变革为品牌提供了新的发展机遇。通过创新的商业模式和有效的私域流量管理&…

弱监督语义/实例/全景分割综述2022

摘要 我们从一个统一的角度总结了现有的高效标签图像分割方法&#xff0c;讨论了一个重要的问题:如何弥合弱监督和密集预测之间的差距——目前的方法大多是基于启发式先验&#xff0c;如跨像素相似性、跨标签约束、跨视图一致性和跨图像关系。最后&#xff0c;对标签高效深度图…

纷享销客海外合规观点与方案:个人隐私数据保护与数据出入境

出海&#xff0c;已不再是企业的“备胎”&#xff0c;而是必须面对的“大考”&#xff01;在这个全球化的大潮中&#xff0c;有的企业乘风破浪&#xff0c;勇攀高峰&#xff0c;也有的企业在异国他乡遭遇了“水土不服”。 面对“要么出海&#xff0c;要么出局”的抉择&#xf…

大功率回馈式负载:行业竞争态势

随着科技的不断发展&#xff0c;大功率回馈式负载在各个行业中的应用越来越广泛。大功率回馈式负载是一种能够将电能回馈到电网的设备&#xff0c;具有节能、环保、高效等优点。然而&#xff0c;随着市场竞争的加剧&#xff0c;大功率回馈式负载行业也面临着诸多挑战。 首先&am…

同城信息房产出租小程序源码系统 完全开源可二次开发 带完整的安装代码包以及搭建教程

系统概述 在数字化转型的浪潮中&#xff0c;房产租赁市场也迎来了新的发展机遇。随着移动互联网的普及&#xff0c;越来越多的用户倾向于通过手机应用或小程序来寻找合适的租房信息。为了满足这一需求&#xff0c;小编给大家分享一款“同城信息房产出租小程序源码系统”&#…

低价和低俗

无底线的低价可不就是低俗了吗&#xff1f; O(∩_∩)O哈哈~ AI说的(引导他说的) 以下几个角度可以进行论证: 低价竞争可能导致质量下降:为了达到极低的价格,商家可能会降低产品或服务的质量标准,使用劣质材料或减少投入。这样可能会影响产品的功能、安全性和使用体验,给消费…

智能合约漏洞类型

Are We There Yet? Unraveling the State-of-the-Art Smart Contract Fuzzers | Proceedings of the IEEE/ACM 46th International Conference on Software Engineering

MySQL-连接查询

049-内连接之等值连接 案例&#xff1a;查询每个员工所在的部门名称&#xff0c;要求显示员工名、部门名。 select e.ename, d.dname from emp e inner join dept d on e.deptnod.deptno;注意&#xff1a;inner可以省略 select e.ename, d.dname from emp e join dept d on…

docker registry-harbor私有镜像仓库安装

本博文将引导您安装和配置Harbor私有镜像仓库。安装前&#xff0c;请确保您已安装Docker和Docker Compose。 前置环境 需要安装docker和docker-compose 下载Harbor Harbor的最新版本可以从GitHub下载。这里以2.9.4版本为例&#xff1a; 下载地址&#xff1a;https://github…

大模型学习之GLM结构

探索GLM&#xff1a;一种新型的通用语言模型预训练方法 随着人工智能技术的不断进步&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域也迎来了革命性的发展。OpenAI的ChatGPT及其后续产品在全球范围内引起了广泛关注&#xff0c;展示了大型语言模型&#xff08;LLM&a…

服务器配置(初始化)

一&#xff1a;什么是云服务器及用途&#xff1a; 云服务器(Elastic Compute Service, ECS)是一种简单高效、安全可靠、处理能力可弹性伸缩的计算服务。其管理方式比物理服务器更简单高效。用户无需提前购买硬件&#xff0c;即可迅速创建或释放任意多台云服务器。 我个人感觉就…

25年后回顾融智学新范式(感受人机互助新时代到了的愉悦,体验人机互助新时代的理解和表达的深入浅出)

25年后回顾融智学新范式 &#xff08;不仅感受人机互助新时代到了的愉悦&#xff0c;更体验人机互助新时代的理解和表达的深入浅出&#xff09; 一句话概述&#xff1a; 《融智学新范式》是一种创新的理论框架&#xff0c;它提出了协同智能主体的概念框架&#xff0c;通过严…

数据结构之链表的经典笔试题

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 目录 203. 移除链表元素 206. 反转链表 876. 链表的中间节点 面试题 02.02. 返回倒数第k个节点 …

想让AI 驱动 UI 测试?墙裂推荐这个自动化工具!

文章概述 本文介绍了什么是视觉测试&#xff0c;功能测试对于视觉测试来说的局限性&#xff0c;视觉测试的重要意义及视觉测试结合python/java两种脚本的案例。 现如今公司不断部署新版本&#xff0c;有些甚至每天都会发布。这种持续部署意味着定期更新或现有代码行正在更改&a…

RabbitMQ概述

RabbitMQ RabbitMQ概述 RabbitMQ是一个开源的消息代理&#xff08;message broker&#xff09;系统&#xff0c;最初由Rabbit Technologies Ltd开发&#xff0c;并在开源社区的支持下不断发展和完善。它提供了强大的消息传递机制&#xff0c;被广泛应用于构建分布式系统和应用…

2003远程桌面端口修改,Windows Server 2003远程桌面端口修改的专业操作指南

在网络安全日益受到重视的今天&#xff0c;修改Windows Server 2003远程桌面的默认端口已成为提高服务器安全性的常规操作。默认情况下&#xff0c;远程桌面使用的端口为3389&#xff0c;这一广为人知的端口号常常成为黑客攻击的目标。因此&#xff0c;通过修改远程桌面端口&am…

JVM的几种常见垃圾回收算法

引言&#xff1a; Java Virtual Machine&#xff08;JVM&#xff09;作为Java程序运行的核心&#xff0c;其垃圾回收&#xff08;Garbage Collection, GC&#xff09;机制在内存管理中起着至关重要的作用。垃圾回收算法是JVM性能优化的重要方面。本文将详细介绍几种常见的垃圾回…

Spring Cloud Stream整合RocketMQ

Spring Cloud Stream整合RocketMQ 这里书接上回&#xff0c;默认你已经搭建好了RocketMQ主从异步集群&#xff0c;前面文章已经介绍过搭建方法。 1、Spring Cloud Stream介绍 Spring Cloud Stream是一个框架&#xff0c;用于构建与共享消息系统连接的高度可扩展的事件驱动微服…

11. 利用MS为Lammps ReaxFF建模(PE/聚乙烯)基础-2

来源&#xff1a; “码农不会写诗”公众号 链接&#xff1a;利用MS为Lammps ReaxFF建模(PE/聚乙烯)基础-2 文章目录 01 msi2lmp工具简介1. 编译生成msi2lmp可执行文件2. 使用方式 02 赋予模型CVFF力场03 导出car/mdf文件04 生成data文件05 data文件进一步处理 文接上篇 上篇利用…

大模型高级 RAG 检索策略之流程与模块化

我们介绍了很多关于高级 RAG&#xff08;Retrieval Augmented Generation&#xff09;的检索策略&#xff0c;每一种策略就像是机器中的零部件&#xff0c;我们可以通过对这些零部件进行不同的组合&#xff0c;来实现不同的 RAG 功能&#xff0c;从而满足不同的需求。 今天我们…