数据结构:大顶堆、小顶堆
堆是其中一种非常重要且实用的数据结构。堆可以用于实现优先队列,进行堆排序,以及解决各种与查找和排序相关的问题。本文将深入探讨两种常见的堆结构:大顶堆和小顶堆,并通过 C++ 语言展示如何实现和使用它们。
一、定义
堆是一种完全二叉树。完全二叉树的定义:所有节点从上往下,从左往右的依次排列,不能有空位置,是为完全二叉树。
下面是完全二叉树和不完全二叉树的示意图:
大顶堆:
根节点(堆顶元素)是所有节点中的最大值(父节点都大于左右子节点)。大顶堆常用于实现优先队列,且可用于构建堆排序算法。
小顶堆:
小顶堆中的根节点是所有节点中的最小值(父节点都小于左右子节点)。小顶堆常用于问题如:查找流中的前 K 个最小元素。
二、实现
通常用 数组 来实现:具体方法就是将二叉树的结点按照 层级顺序 放入数组中, 根结点在 位置1(数组索引0处不存储数据),它的子结点在位置2和3,而子结点的子结点则分别在位置4,5,6和7,以此类推
- 如果一个结点的位置为 k,则它的父结点的位置为 k/2
- 两个子结点的位置则分别为 2k 和 2k+1
2.1 Insert
堆是用 数组 完成数据元素的存储的,由于数组的底层是一串连续的内存地址,所以要往堆中插入数据,只能往数组中从索引0处开始,依次往后存放数据,但是堆中对元素的顺序是有要求的,每一个结点的数据要 大于等于它的两个子结点的数据,所以每次插入一个元素,都会使得堆中的数据顺序变乱,这个时候就需要通过一些方法,让刚才插入的这个数据放入到合适的位置
所以,如果往堆中新插入元素,只需要不断的比较新结点 a[k] 和它的父结点 a[k/2] 的大小,然后根据结果完成数据元素的交换,就可以完成堆的有序调整。
2.1 delMax
由大顶堆的特性可以知道,索引1处的元素,也就是根结点就 是最大的元素,把根结点的元素删除后,需要有一个新的根结点出现,这时可以 暂时把堆中最后一个元素放到索引1处,充当根结点,但是它有可能不满足堆的有序性需求,这个时候就需要通过一些方法,让这个新的根结点放入到合适的位置
所以,当删除掉最大元素后,只需要将最后一个元素放到索引1处,并不断的拿着当前结点 a[k] 与它的子结点a[2k] 和 a[2k+1] 中的较大者交换位置,即可完成堆的有序调整。
三、堆排序
要求:给你一个数组 {4,6,8,5,9} , 要求使用堆排序法,将数组升序排序。
实现步骤:
- 构造堆
- 得到堆顶元素,这个值就是最大值
- 交换堆顶元素和数组中的最后一个元素,此时所有元素中的最大元素已经放到合适的位置
- 对堆进行调整,重新让除了最后一个元素的剩余元素中的最大值放到堆顶
- 重复2~4这个步骤,直到堆中剩一个元素为止
3.1 堆构造过程
堆的构造,最直观的想法就是另外再创建一个新数组,然后从左往右遍历原数组,每得到一个元素后,添加
到新数组中,并通过上浮,对堆进行调整,最后新的数组就是一个堆
上述的方式虽然很直观,也很简单,但是可以用更聪明一点的办法完成它
创建一个新数组,把原数组0 ~ length-1的数据拷贝到新数组的 1 ~ length 处,再从新数组 长度的一半 处开始往 1索引 处扫描(从右往左),然后对扫描到的每一个元素做下沉调整即可
为什么是新数组长度的一半?
因为新数组是一个无序堆,长度的一半之后的结点为叶子结点;叶子结点不需要要下沉调整
1.假设给定无序序列结构如下:
2.此时我们从最后一个非叶子结点开始(叶结点自然不用调整,第一个非叶子结点arr.length/2-1=5/2-1=1,也就是下面的6结点),从左至右,从下至上进行调整。
3.找到第二个非叶节点4,由于[4,9,8]中9元素最大,4和9交换。
4.这时,交换导致了子根[4,5,6]结构混乱,继续调整,[4,5,6]中6最大,交换4和6。
3.2 堆排序过程
对构造好的堆,只需要做 类似于堆的删除操作,就可以完成排序:
- 将堆顶元素和堆中最后一个元素交换位置
- 通过对堆顶元素下沉调整堆,把最大的元素放到堆顶 (此时最后一个元素不参与堆的调整,因为最大的数据已经到了数组的最右边)
- 重复1~2步骤,直到堆中剩最后一个元素
1.将堆顶元素9和末尾元素4进行交换
2.重新调整结构,使其继续满足堆定义
3.再将堆顶元素8与末尾元素5进行交换,得到第二大元素8
4.后续过程,继续进行调整,交换,如此反复进行,最终使得整个序列有序
3.3 总结堆排序的基本思路
1).将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆
2).将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端:
3).重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤
直到整个序列有序。
至于完整的代码实现和动画显示,可以参考我的文章 - 排序算法基础
相关文章:

数据结构:大顶堆、小顶堆
堆是其中一种非常重要且实用的数据结构。堆可以用于实现优先队列,进行堆排序,以及解决各种与查找和排序相关的问题。本文将深入探讨两种常见的堆结构:大顶堆和小顶堆,并通过 C 语言展示如何实现和使用它们。 一、定义 堆是一种完…...

电加热热水器上架亚马逊美国站需要的UL174报告
电加热热水器上架亚马逊美国站需要的UL174报告 家用热水器出口美国需要办理UL174测试报告。 热水器就是指通过各种物理原理,在一定时间内使冷水温度升高变成热水的一种装置。分为制造冷气部分和制造热水部分。其实这两个部分又是紧密地联系在一起,密不可…...

使用visual studio写一个简单的c语言程序
官网下载visual studio,社区版免费的 https://visualstudio.microsoft.com/zh-hans/ 下载好以后选择自己的需求进行安装,我选择了两个,剩下的是默认。 创建文件:...
怎么创建facebook广告
创建Facebook广告的文章应由本人根据自身实际情况书写,以下仅供参考,请您根据自身实际情况撰写。 创建Facebook广告的步骤: 确定目标受众和广告主题:首先需要明确你的目标受众是谁,他们有什么特点,以及你想…...

pdf怎么转成高清图?pdf在线转换器推荐分享
在日常的工作或者学习中,有时候会需要将编辑好的pdf转高清图片,这样更方便我们后续使用,那么怎么将pdf转图片(https://www.yasuotu.com/pdftopic)还能保持清晰呢?下面介绍一款pdf转换工具,支持p…...

postgresql 查询缓慢原因分析
pg_stat_activity 最近发现系统运行缓慢,查询数据老是超时,于是排查下pg_stat_activity 系统表,看看有没有耗时的查询sql SELECT pid, state, query, query_start, backend_type FROM pg_stat_activity WHERE state active AND query LIK…...

N65总账凭证管理凭证查询(sql)
--核算账簿 select code , name , pk_setofbook from org_setofbook where ( pk_setofbook in ( select pk_setofbook from org_accountingbook where 1 1 and ( pk_group N0001A11000000000037X ) and ( accountenablestate 2 ) ) ) order by code;--核算账簿 select code …...

投资1300万欧元!芬兰正式启动量子旗舰项目
内容来源:量子前哨(ID:Qforepost) 编辑丨慕一 编译/排版丨卉可 琳梦 深度好文:800字丨8分钟阅读 近日,芬兰研究委员会向新启动的芬兰量子旗舰(FQF)项目拨款1300万欧元…...

【3分钟开服】幻兽帕鲁服务器一键部署保姆教程
在帕鲁的世界,你可以选择与神奇的生物「帕鲁」一同享受悠闲的生活,也可以投身于与偷猎者进行生死搏斗的冒险。帕鲁可以进行战斗、繁殖、协助你做农活,也可以为你在工厂工作。你也可以将它们进行售卖,或肢解后食用。 引用自&#x…...
PandaWallet :Web3.0世界的入口
如果说互联网的普及和发展造就了移动支付,那么Web3的到来则书写了加密支付的新篇章,并将加密钱包的发展推向新高潮。 传统电子钱包的功能是储存资产与移动支付。加密钱包在储存资产与移动支付的基础上,增加了身份标识的功能。这也是Web3中用户…...

微软Azure-openAI 测试调用及说明
本文是公司在调研如何集成Azure-openAI时,调试测试用例得出的原文,原文主要基于官方说明文档简要整理实现 本文已假定阅读者申请部署了模型,已获取到所需的密钥和终结点 变量名称值ENDPOINT从 Azure 门户检查资源时,可在“密钥和…...

java 图书管理系统 spring boot项目
java 图书管理系统ssm框架 spring boot项目 功能有管理员模块:图书管理,读者管理,借阅管理,登录,修改密码 读者端:可查看图书信息,借阅记录,登录,修改密码 技术&#…...

Ubuntu系统安装 Redis
环境准备 Ubuntu 系统版本:22.04.3Redis 版本:6.2.12 检查本地 make 环境 make -version若没有安装,则需要安装 sudo apt install make检查本地 gcc 环境 gcc -version若没有安装,则需要安装 sudo apt install gcc。 sudo a…...

简单记录一下如何安装python以及pycharm(图文教程)(可供福建专升本理工类同学使用)
本教程主要给不懂计算机的或者刚刚开始学习python的同学(福建专升本理工类)&网友学习使用,基础操作,比较详细,其他问题等待补充! 安装Python 1.进入python官网(https://www.python.org/&a…...

浏览器内存泄漏排查指南
1、setTimeout执行原理 使用setInterval/setTimeOut遇到的坑 - 掘金 2、Chrome自带的Performance工具 当我们怀疑页面发生了内存泄漏的时候,可以先用Performance录制一段时间内页面的内存变化。 点击开始录制执行可能引起内存泄漏的操作点击停止录制 如果录制结束…...
ClickHouse(22)ClickHouse集成HDFS表引擎详细解析
文章目录 HDFS用法实施细节配置可选配置选项及其默认值的列表libhdfs3 支持的ClickHouse 额外的配置限制 Kerberos 支持虚拟列 资料分享系列文章clickhouse系列文章知乎系列文章 HDFS 这个引擎提供了与Apache Hadoop生态系统的集成,允许通过ClickHouse管理HDFS上的…...

idea报错 :(java: 找不到符号)
java: 找不到符号 符号: 变量 adminService 位置: 类 com.example.controller.WebController 查到网上一个办法:因为项目是maven:先点clean在点package...
设计软件最重要的目标是可理解性?
当您设计一款软件时,设计时最重要的一点就是可理解性。安全性、性能和正确性都很重要,但它们次优于可理解性。 被误解的软件会产生Bug缺陷 如果软件的实施者和维护者对软件存在误解,那么软件最终就会出现缺陷。主要缺陷。这些缺陷有多种形式…...

酒店|酒店管理小程序|基于微信小程序的酒店管理系统设计与实现(源码+数据库+文档)
酒店管理小程序目录 目录 基于微信小程序的酒店管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员模块的实现 (1) 用户信息管理 (2) 酒店管理员管理 (3) 房间信息管理 2、小程序序会员模块的实现 (1)系统首页 ࿰…...

C++ 数论相关题目,博弈论,SG函数,集合-Nim游戏
给定 n 堆石子以及一个由 k 个不同正整数构成的数字集合 S 。 现在有两位玩家轮流操作,每次操作可以从任意一堆石子中拿取石子,每次拿取的石子数量必须包含于集合 S ,最后无法进行操作的人视为失败。 问如果两人都采用最优策略,…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...