数据结构 - 堆

news2024/12/26 9:23:38

这篇博客将介绍堆的概念以及堆的实现。

1. 堆的定义:
首先堆的元素按照是完全二叉树的顺序存储的。
且堆中的某个节点总是不大于不小于其父节点的值。
根节点最大的堆叫做大堆,根节点最小的堆叫小堆。逻辑结构如下图所示:

大堆和小堆的存储方式是利用一个一维数组进行存储的,其物理存储结构如下:

因此我们可以利用数组的下标,通过子节点找到父节点,或通过父节点找到子节点,其关系如下:
        parent = ( child - 1 ) / 2; child =  parent * 2 + 1;
2. 堆的创建
那么,现在我们有一个数组 a[] = {8, 1, 4, 5, 3, 2};  在逻辑上可以看成一个完全二叉树,但是它还不是一个堆,我们要如何将其构建成一个堆呢?这里我们以构建一个小堆为例,我们从倒数第一个非叶子节点的子树开始调整,一直调整到根节点的树,就可以调整成堆,示意图如下:
3. 堆的插入 
堆的插入一般插入到数组尾部,在进行向上调整算法,直到满足堆的定义 ,示意图如下:

4. 堆的删除
 堆的删除是删除堆顶的数据,将堆顶的根数据与最后一个数据交换,在删除数组的最后一个元素,在进行向下调整堆。示意图如下:

5. 代码实现
typedef int HPDataType;

typedef struct Heap
{
	HPDataType* a;
	int size;
	int capacity;
}HP;

void HeapInit(HP* php);//堆的初始化
void HeapDestroy(HP* php);//内存释放
void HeapPush(HP* php, HPDataType x);//堆的创建
void HeapPop(HP* php);//删除根节点
HPDataType HeapTop(HP* php);//返回根节点
bool HeapEmpty(HP* php);//判空
int HeapSize(HP* php);//堆大小
void HeapInit(HP* php)
{
	assert(php);
	php->a = NULL;
	php->capacity = 0;
	php->size = 0;
}

void HeapDestroy(HP* php)
{
	assert(php);
	free(php->a);
	php->a = NULL;
	php->size = 0;
	php->capacity = 0;
}

void Swap(HPDataType* p1, HPDataType* p2)
{
	HPDataType tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

void Adjustup(HPDataType* a, int child)//小堆调整
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] < a[parent])
		{
			Swap(&a[child], &a[parent]);

			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

void HeapPush(HP* php, HPDataType x)
{
	if (php->size == php->capacity)
	{
		int newCapacity = php->capacity == 0 ? 4 : php->capacity * 2;
		HPDataType* tmp = (HPDataType*)realloc(php->a, newCapacity * sizeof(HPDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		php->a = tmp;
		php->capacity = newCapacity;
	}
	php->a[php->size] = x;
	php->size++;
	Adjustup(php->a, php->size-1);
}

void AdjustDown(int* a, int n, int parent)//前提:左子树和右子树是大/小堆 
{
	int child = parent * 2 + 1;
	while (child < n)
	{
		//选出左右孩子中 小/大 的那个
		if (child+1 < n && a[child + 1] < a[child])//右孩子可能不存在
		{
			child++;
		}
		if (a[parent] > a[child])
		{
			Swap(&a[parent],&a[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

void HeapPop(HP* php)//删除堆顶的数据
//首尾数据交换,再删除,再调堆
{
	assert(php);
	assert(!HeapEmpty(php));
	Swap(&php->a[0], &php->a[php->size-1]);
	php->size--;
	AdjustDown(php->a,php->size,0);
}

HPDataType HeapTop(HP* php) 
{
	assert(php);
	assert(!HeapEmpty(php));
	return php->a[0];
}

bool HeapEmpty(HP* php)
{
	assert(php);
	return php->size == 0;
}

int HeapSize(HP* php) 
{
	assert(php);
	return php->size;
}
6. 结果
完全二叉树:
int a[] = { 8,1,4,5,3,2 };
建堆:

打印根节点,删除根节点,内存释放: 
while (!HeapEmpty(&hp))
{
	int top = HeapTop(&hp);
	printf("%d\n", top);
	HeapPop(&hp);
}

HeapDestroy(&hp);


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring揭秘:ApplicationContextAware应用场景及实现原理!

内容概要 ApplicationContextAware接口能够轻松感知并在Spring中获取应用上下文&#xff0c;进而访问容器中的其他Bean和资源&#xff0c;这增强了组件间的解耦&#xff0c;了代码的灵活性和可扩展性&#xff0c;是Spring框架中实现高级功能的关键接口之一。 核心概念 它能用…

腾讯云学生服务器详细介绍_学生服务器价格_学生机申请流程

2024年腾讯云学生服务器优惠活动「云校园」&#xff0c;学生服务器优惠价格&#xff1a;轻量应用服务器2核2G学生价30元3个月、58元6个月、112元一年&#xff0c;轻量应用服务器4核8G配置191.1元3个月、352.8元6个月、646.8元一年&#xff0c;CVM云服务器2核4G配置842.4元一年&…

Java开发从入门到精通(一):Java的基础语法高阶

Java大数据开发和安全开发 &#xff08;一)Java的流程控制1.1 分支语句1.1.1 IF分支语句第一种IF语句第二种IF-ELSE语句第三种IF-ELSE IF-ELSE语句if语句使用的几个常见问题 1.1.2 switch分支语句switch分支的执行流程switch分支的导学案例:电子备忘录if、switch的比较&#xf…

关于JavaScript你该知道的(错误)和不知道的(技巧)

关于JS你该知道的(错误)和不知道的(技巧) 你该知道的(容易犯的错误) 忽略异步函数// Incorrect: Ignoring the asynchronous nature of setTimeout console.log("Start"); setTimeout(() => console.log("Timeout"), 0); console.log("End&q…

【实验】学习实验debug,以及经验感悟

记录两次独立解决问题的过程&#xff1a; 目前来看&#xff0c;问题分为几种&#xff1a; 抄代码的时候抄错了&#xff0c;比如dim1写成dim0这种 逻辑错误&#xff0c;如果两份代码没什么差别的话&#xff0c;那么肯定是逻辑错误。 下面的两个问题都是逻辑错误&#xff0c;因为…

【C++精简版回顾】21.迭代器(未完成)

1.什么是迭代器&#xff1f; 用来遍历容器&#xff0c;访问容器数据。 2.迭代器使用 1.初始化 //初始化 list<int> mylist;//list的整数对象 list<int>::iterator iter;//list内部类&#xff0c;迭代器对象(正向输出) list<int>::reverse_iterator riter;//…

Android使用WebView打开网页链接(内嵌H5网页)的两种方式之一

发布Android应用&#xff0c;除了用原生开发外&#xff0c;更多是采用内嵌H5网页的方式来做&#xff0c;便于更新以及多平台使用。 一、第一种方式是直接通过WebView打开外部H5链接。 新建Android工程 直接创建一个工程&#xff0c;点击运行就可以了&#xff0c;打开是个空页…

PaddlePaddle----基于paddlehub的OCR识别

Paddlehub介绍 PaddleHub是一个基于PaddlePaddle深度学习框架开发的预训练模型库和工具集&#xff0c;提供了丰富的功能和模型&#xff0c;包括但不限于以下几种&#xff1a; 1.文本相关功能&#xff1a;包括文本分类、情感分析、文本生成、文本相似度计算等预训练模型和工具。…

基于springboot精品在线试题库系统论文

摘 要 使用旧方法对作业管理信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在作业管理信息的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。这次开发的精品在线试题库系…

022—pandas 根据时间段转换为各小时的秒数

前言 本例中&#xff0c;有一些时间段数据&#xff0c;需要将这些时间段里的时间以小时为分组&#xff0c;将24个小时段中每个小时所占用的秒数计算出来。 需求&#xff1a; 以第一条数据为例&#xff0c;它所在两个小时&#xff0c;7点段占用24分钟15秒&#xff0c;8点段54…

【一起学习Arcade】(5):属性规则实例_计算规则

属性规则可改善地理数据库数据集的编辑体验并提高数据完整性。 这些规则均为用户定义的规则&#xff0c;可用于自动填充属性、在编辑操作期间限制无效编辑&#xff0c;以及对现有要素执行质量保证检查。 属性规则分为3类&#xff1a;计算、约束和验证。 这一篇介绍计算规则&…

光谱整形1

华为张德江&#xff1a;下一代光传送网将走向400G80波WDM系统_通信世界网 (cww.net.cn) 张德江指出&#xff0c;400G WDM系统具有三大基本特征&#xff1a;支持400G80波&#xff0c;单纤32T超大容量&#xff0c;传输距离与100G相当&#xff1b;支持32维以上的光交叉&#xff1…

为什么不从独立服务器中转向云或其他方案呢?

传统的专用服务器&#xff0c;如香港服务器租赁、重庆服务器租赁等&#xff0c;是最强大、最稳定的业务托管类型之一。您将获得比任何其他托管计划更多的管理权限和卓越的性能&#xff0c;并且您可以控制整个服务器上的几乎所有内容。 当然&#xff0c;专用服务器也是在线业务…

昏暗场景增强-低照度增强-弱光增强(附代码)

引言 随着现代科技的发展&#xff0c;图像采集设备已经渗透到生活的方方面面&#xff0c;然而在昏暗场景、低照度或弱光条件下&#xff0c;图像的质量往往受到严重影响&#xff0c;表现为亮度不足、对比度低下、色彩失真以及细节丢失等问题。这类图像对于人眼识别和计算机视觉…

大数据冷热分离方案

数据冷热分离方案 1、背景 ​ 随着业务的发展&#xff0c;在线表中的数据会逐渐增加。常规业务都有冷热数据现象明显的特性&#xff08;需要访问的都是近期产生的热数据&#xff1b;时间久远的冷数据出于备份、备案溯源等诉求会进行在线保留&#xff09;。在业务表数据 量可控…

自动化测试之web自动化(Selenium)

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

基础小白快速入门并行计算------>我们为什么要学习并行计算

什么是并行计算&#xff1f; 随着计算机的不断发展&#xff0c;我们处理的数据不断变多&#xff0c;需要更大得到处理能力、我们希望计算机有着更大更强壮的计算能力&#xff0c;由于cpu的运行能力有限&#xff0c;我们便想到了将多个cpu进行串联计算问题&#xff0c;这也就是我…

第五十二回 戴宗二取公孙胜 李逵独劈罗真人-飞桨AI框架安装和使用示例

吴用说只有公孙胜可以破法术&#xff0c;于是宋江请戴宗和李逵去蓟州。两人听说公孙胜的师傅罗真人在九宫县二仙山讲经&#xff0c;于是到了二仙山&#xff0c;并在山下找到了公孙胜的家。 两人请公孙胜去帮助打高唐州&#xff0c;公孙胜说听师傅的。罗真人说出家人不管闲事&a…

接口测试,后端接口还没开发完,如何测?解决看这一篇就够了......

前言 在测试的时候经常会碰到后端开发工程师的接口还没有开发完成&#xff0c;但是测试任务已经分配过来。没有接口怎么测试呢&#xff1f; 测试人员可以通过 mock server 自己去造一个接口来访问。mock server 可用于模拟真实的接口。收到请求时&#xff0c;它会根据配置返回…

【24春招/简历】如果技术和学历不行,如何包装自己在春招中占得先机?突出你的亮点!

面试讲什么 学历&#xff1a; 行情 要美化&#xff08;吹牛&#xff09; 面试很好 技术能力 让面试官知道你会哪些技术&#xff0c;尽量细节 “熟悉spring” > ioc流程&#xff0c;Bean的生命周期&#xff0c;循环依赖&#xff0c;常见注解 熟悉redis > 缓存穿透&…