堆以及堆的实现
文章目录
- 堆的概念
- 堆的实现
- HeapPush
- HeapPop
- HeapTop HeapSize HeapEmpty
- 堆的应用
堆的概念
- 堆是一颗完全二叉树
- 每个结点的值都小于子结点的值,这颗二叉树为小根堆
- 每个结点的值都大于子结点的值,这颗二叉树为大根堆
- 堆的定义如下:n个元素的序列{k1,k2,ki,…,kn}当且仅当满足下关系时,称之为堆。

堆的性质 - 堆中某个节点的值总是不大于或不小于其父节点的值;
- 堆总是一棵完全二叉树。
堆的实现
在讲堆的实现前,我们首先要知道堆需要实现的功能。
- HeapPush
- HeapPop(删除根结点)
- HeapTop
- HeapSize
- HeapEmpty
接下来我们要先创建和销毁一个堆。
typedef int HeapType;
typedef struct Heap
{HeapType* arr;int size;int capacity;
}Hp;
void HeapInit(Hp* php)
{assert(php);php->arr = NULL;php->capacity = php->size = 0;
}
void HeapDestroy(Hp* php)
{assert(php);free(php->arr);php->arr = NULL;php->capacity = php->size = 0;
}
HeapPush
实现HeapPush时难点在于如何保持整体是一个堆。
即在一个堆的后面插入一个值,那么这棵完全二叉树大概率不会是堆,那么我们需要将这个值和其父结点比较,再根据需要交换值,也就是AdjustUp。
那么接下来以小根堆为例,实现HeapPush。
void Swap(HeapType* a, HeapType* b)
{HeapType tmp = *a;*a = *b;*b = tmp;
}
void AdjustUp(HeapType* arr, int child)
{int parent = (child - 1) / 2;while (child>0){if (arr[child] < arr[parent]){Swap(&arr[child], &arr[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}
void HeapPush(Hp* php, HeapType x)
{assert(php);if (php->size == php->capacity){int newcapacity = (php->capacity == 0 ? 4 : 2 * php->capacity);HeapType * tmp = (HeapType*)realloc(php->arr,newcapacity * sizeof(HeapType));if (!tmp){perror("realloc fail!");exit(-1);}php->arr = tmp;php->capacity = newcapacity;}php->arr[php->size] = x;php->size++;AdjustUp(php->arr, php->size - 1);
}
HeapPop
实现HeapPop也是和HeapPush一样,需要考虑的是如何维持整体完全二叉树是一个堆,由于我们删除的是根结点,如果将根结点的子结点向上调整,那么整体二叉树就会空出一个位置,导致变成非完全二叉树。
这里的解决办法是将根结点和最后一个结点交换,删除最后一个结点,然后再对根结点进行向下调整。
void AdjustDown(HeapType* a, int n, int parent)
{int child = 2 * parent + 1;while (child<n){if (child + 1 < n && a[child] > a[child + 1]){child++;}if (a[parent] > a[child]){Swap(&a[child], &a[parent]);parent = child;child = 2 * parent - 1;}else{break;}}
}
void HeapPop(Hp* php)
{assert(php);assert(php->size);Swap(&php->arr[0], &php->arr[php->size - 1]);php->size--;AdjustDown(php->arr, php->size, 0);
}
HeapTop HeapSize HeapEmpty
实现了Heap的Push和Pop后,那么取根结点的值和判空、判满也是手到擒来的。
HeapType HeapTop(Hp* php)
{assert(php);assert(php->size);return php->arr[0];
}
size_t HeapSize(Hp* php)
{assert(php);return php->size;
}
bool HeapEmpty(Hp* php)
{assert(php);return php->size == 0;
}
堆的应用
实现了堆那么我们肯定要知道能用在什么地方才行,实际上堆的应用也是非常广泛的:
- 实现堆排序
- 求Top K值问题
- 求中位数、百分位数
等等。
堆的应用还有很多,这里就不一一赘述了。
相关文章:
堆以及堆的实现
文章目录 堆的概念堆的实现HeapPushHeapPop HeapTop HeapSize HeapEmpty堆的应用 堆的概念 堆是一颗完全二叉树每个结点的值都小于子结点的值,这颗二叉树为小根堆每个结点的值都大于子结点的值,这颗二叉树为大根堆堆的定义如下:n个元素的序列…...
使用RabbitMQ实现延时消息自动取消的简单案例
一、流程图 二、导包 <!--消息队列 AMQP依赖,包含RabbitMQ--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency> 三、配置文件 #消息队列 …...
Docker部署(ruoyi案例接上篇Docker之部署前后端分离项目)实施必会!!!!
文章目录 Docker部署前端 Docker部署前端 接上篇博主已经部署好后端Docker部署后端,现在来讲解怎么部署前端 MySQL和redis是不依赖其他任何一个东西的, ruoyi-admin是因为你启动项目的时候是必须连接数据库的 现在去单独启动它 docker start ruoyi-a…...
电脑中已经有多个模组压缩文件,如何通过小火星露谷管理器批量安装
如果已经下载了很多的星露谷模组压缩文件(zip包),可以通过【添加模组】功能,将模组批量解压到Mods文件夹中。 名词解释 为了避免这篇文章的内容看不懂,先解释两个名词。 直装型模组:直接解压到Mods就能生…...
[Linux]如何理解kernel、shell、bash
文章目录 概念总览kernelshell&bash 概念总览 内核(kernel) ,外壳(shell) ,bash kernel kernel是指操作系统中的核心部分,用户一般是不能直接使用kernel的。它主要负责管理硬件资源和提供系统服务,如内存管理、进程管理、文件…...
C++:Vector的使用
一、vector的介绍 vector的文档介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以…...
Redis之事务(详细解析)
请直接看原文:不能回滚的Redis事务还能用吗 - 知乎 (zhihu.com) ------------------------------------------------------------------------------------------------------------------------------ 1、Redis事务的概念: Redis 事务的本质是一组命令的集合。…...
Java项目:39 springboot007大学生租房平台的设计与实现
作者主页:源码空间codegym 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统有管理员、房东和用户 【主要功能】 1、后台:房源管理、信息审批管理、订单信息管理、房东管理、用户管理 2、前台࿱…...
安卓内存信息查看
目录 前言一、Android查看内存相关信息的方法1.1 通过 adb shell 获取内存信息1.2 通过编程方式获取内存信息1.3 adb shell 获取应用程序内存使用情况1.4 free指令 二、总结 前言 一、Android查看内存相关信息的方法 1.1 通过 adb shell 获取内存信息 C:\Users\henry.xue>…...
Positional Encoding 位置编码
Positional Encoding 位置编码 flyfish Transformer模型没有使用循环神经网络,无法从序列中学习到位置信息,并且它是并行结构,不是按位置来处理序列的,所以为输入序列加入了位置编码,将每个词的位置加入到了词向量中…...
MySql、Navicat 软件安装 + Navicat简单操作(建数据库,表)
一、MySql、Navicat 软件安装 及正常使用 MySql下载+安装: 检查安装情况: 配置环境变量: 搞定了!!! 可以登陆试哈哈哈 连接navicat 开始创建数据库 二、 商品种类表 - commoditytype int …...
逆向案例五、爬取b站评论,表单MD5加密
1.便捷写爬虫网站: Convert curl commands to code 使用流程:又点击想要抓的包,复制URL(base)格式复制 在上面链接中粘贴即可 2.找到含有评论的包(即main?oid):观察表单发现两处参数在变化&…...
010-原型链
原型链 1、概念2、原理3、new 操作符原理4、应用 1、概念 原型链:javascript的继承机制,是指获取JavaScript对象的属性会顺着其_proto_的指向寻找,直至找到Object.prototype上。 2、原理 💡 Tips:构造函数 Fn&#…...
Electron-builder打包安装包——编译篇
突然有一天想打包个桌面程序,没有打包过,经过九牛二虎之力终于打包出来,在此感谢那些热于分享的前辈! 本篇只讲打包运行和出现的问题 一、准备工作:提前下载相关资源包,否则在国内环境下可能因为网络问题…...
Red Hat系统升级内核版本
查看当前内核版本 uneme -r yum list kernel升级内核 yum update -y kernel检查升级后的内核版本 uneme -r yum list kernel升级系统中已安装的软件包到最新版本(过程时间较长) 目前只升级了系统内核,系统相关的安装包还是老的࿰…...
Java集合set之HashSet、LinkedHashSet、TreeSet的区别?
Java的集合中主要由List,Set,Queue,Map构成,Set特点:存取无序,不可以存放重复的元素,不可以用下标对元素进行操作。 HashSet 作为Set容器的代表子类,HashSet经常被用到,…...
全方位碾压chatGPT4的全球最强模型Claude 3发布!速通指南在此!保姆级教学拿脚都能学会!
🎉🎉欢迎光临,终于等到你啦🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟持续更新的专栏《Spring 狂野之旅:从入门到入魔》 &a…...
upload-Labs靶场“11-15”关通关教程
君衍. 一、第十一关 %00截断GET上传1、源码分析2、%00截断GET上传 二、第十二关 %00截断POST上传1、源码分析2、%00截断POST上传 三、第十三关 文件头检测绕过1、源码分析2、文件头检测绕过 四、第十四关 图片检测绕过上传1、源码分析2、图片马绕过上传 五、第十五关 图片检测绕…...
linux-rpm命令
rpm命令管理程序包:安装、升级、卸载、查询和校验 1、忽略依赖关系安装/卸载包 安装:rpm -Uvh 软件包名 --nodeps 卸载:rpm -e 软件包名 --nodes!!!!慎用!!!…...
如何利用python实现自己的modbus-tcp库
如果你想使用纯Socket编程来实现Modbus TCP通讯,而不是依赖于Modbus库,你需要理解Modbus TCP协议的细节,并能够手动构建和解析Modbus消息。以下是一个简单的示例,展示了如何使用Python的socket库来实现Modbus TCP通讯: 了解Modbus TCP协议: Modbus TCP协议使用TCP作为底层…...
ToastFish:终极Windows通知栏摸鱼背单词神器,上班族必备的隐蔽学习工具
ToastFish:终极Windows通知栏摸鱼背单词神器,上班族必备的隐蔽学习工具 【免费下载链接】ToastFish 一个利用摸鱼时间背单词的软件。 项目地址: https://gitcode.com/GitHub_Trending/to/ToastFish 你是否厌倦了枯燥的背单词软件?Toas…...
SystemC随机验证环境构建:从约束生成到覆盖率驱动的自动化测试
1. 项目概述:从确定性仿真到随机验证的跨越在芯片设计和验证领域,SystemC 早已不是陌生的名字。它作为 C 的类库扩展,为系统级建模和硬件/软件协同验证提供了强大的框架。然而,很多刚接触 SystemC 验证的朋友,往往止步…...
从Caffeine源码到实战:手把手教你用Checker Framework给Java代码做‘体检’
从Caffeine源码到实战:手把手教你用Checker Framework给Java代码做‘体检’ 在阅读Caffeine这样的高质量开源项目时,细心的开发者常会注意到一些独特的编译注解——比如Nullable、GuardedBy这类标记。这些看似简单的注解背后,其实隐藏着一个强…...
新手避坑指南:STM32用Makefile编译时,遇到‘junk at end of line’错误怎么办?
STM32 Makefile编译实战:彻底解决junk at end of line汇编错误 第一次用Makefile编译STM32项目时,看到满屏的junk at end of line错误提示,确实容易让人头皮发麻。这就像你兴冲冲地下载了一个开源项目准备大展身手,结果刚执行make…...
衍射光学元件微结构
衍射光学元件(DOEs)是利用刻蚀微结构的衍射特性将入射光束转换为所需光分布的光学元件,利用结构的周期性或无周期性分别创建离散的(分束器)或连续的模式(光束整形器、扩散器)。由于这些元件的工作原理是基于光通过这些图案表面的衍射,因此DOE光束整形器和…...
《字节码到JVM:Java基础核心知识点全解析(小林八股·上)》
🔥个人主页:北极的代码(欢迎来访) 🎬作者简介:java后端学习者 ❄️个人专栏:苍穹外卖日记,SSM框架深入,JavaWeb ✨命运的结局尽可永在,不屈的挑战却不可须臾或…...
自主Agent的下一代智能系统
如果说上一代AI是“单打独斗”的数字大脑,那么自主Agent(智能体)的下一代——“人机环境系统智能”,就是“人机共生”的实体生态。它标志着AI正在从虚拟的比特世界,跨越到与人类、物理环境深度融合的现实世界。我们可以…...
《利红AI企业级应用新标准等级体系》正式发布
各相关单位及合作伙伴: 为助力企业推动人工智能技术在实体经济中的科学落地,经公司研究决定,现正式发布《利红AI企业级应用新标准等级体系》(以下简称"本标准")。现将有关事项公告如下: 一、新…...
【MATLAB源码-第439期】基于MATLAB的APSK与QAM高阶调制在Saleh非线性功放下BER和EVM性能对比
操作环境:MATLAB 2024a1、算法描述摘要 高阶数字调制技术是现代无线通信和卫星通信系统提高频谱利用率的重要方法。QAM 调制通过同相分量和正交分量的幅度组合形成二维星座,在较高信噪比条件下能够获得较高的信息承载能力。APSK 调制则采用多环幅相结构&…...
别再被0.1+0.2≠0.3搞懵了!用Python和Java代码手把手拆解IEEE-754浮点数存储
浮点数精度之谜:用代码揭开0.10.2≠0.3的真相 当你在Python控制台输入0.1 0.2时,得到的不是预期的0.3,而是0.30000000000000004。这个看似简单的数学运算为何会出现如此"诡异"的结果?本文将带你用Python和Java代码深入…...
