算法通过村第十四关-堆|青铜笔记|堆结构

文章目录

  • 前言
  • 堆的概念和特征
  • 堆的构成过程
  • 插入操作
  • 删除操作
  • 总结


前言


若执于空,空亦为障。 --彼得·马西森《雪豹》

堆结构是一种非常重要的基础数据结构,也是算法的重要内容,很多题目甚至只能通过用堆来进行,所以我们必须明确什么类型的题目可以使用堆,以及如何使用堆来解决。由于堆的结构和维护的过程很复杂,因此一般面试不需要手写堆的实现,但是在Java、python、C++已经提供了一些工具,因此需要知道思路就可以了。

这里主要简介堆的使用,如何进行增删改查,不用管代码怎么写,后面我们会继续介绍怎么使用堆解决问题的。

堆的概念和特征

堆是将一组数据按照完全二叉树的存储顺序(推荐⭐⭐⭐: 算法通过村第六关-树青铜笔记|中序后序_师晓峰的博客-CSDN博客),将数据存储在一个一维数组中的结构。堆有两种结构,一种称为大顶堆,一种称为小顶堆,如图下:

  • 小顶堆:任意节点的值均小于它的左右孩子,并且最小值位于堆顶,即根节点处。
  • 大顶堆:任意节点的值均大于它的左右孩子,并且最大值位于堆顶,即根节点处。

当然有些地方叫大根堆,小根堆,或者最大堆、最小堆都是一个意思。大小的特征都是类似的,只是比较的时候按照大的来点定还是按照小的来定。我们这里介绍先按照最大堆来进行,后面的题目我们根据条件来定。

小顶堆:
在这里插入图片描述
大顶堆:
在这里插入图片描述
既然是将一组数据按照树的结构存储在一堆数组中,而且还是完全二叉树,那么父子之间的关系的建立就很重要了。

有个概念需要注意一下,我们在做题的时候经常会看到有地方叫做堆,有些地方叫优先队列,两者是什么关系呢?

优先队列:说到底还是一种队列,他的工作就是poll()/peek()出队列中的最大或者最小的那个元素,所以叫做带有优先级别的队列。能够实现这样的功能的策略不一定是堆。例如:二项堆、平衡树、线段树、C++里面还用二进制分组vector来实现一个优先队列。

堆:是一个很大的概念,它并不一点是完全二叉树。我们之前用完全二叉树是因为这个容易呗数组存储,但是除了这种二叉堆之外,还有二项堆、斐波那契堆。这种堆就不属于二叉树了。

所以说,优先队列和堆不是一个同level的概念,但是Java中PriorityQueue就是采用堆实现的,因此在Java的领域中,我们可以认为堆就是优先队列,优先队列也就是堆,换个场景的话就不太行了。

堆的构成过程

使用数组构建堆时,就是按照层次将所有元素依次放入二叉树中,使其成为二叉树,然后再不断的调整,最终使其符合堆的结构。

这里我们先假设一个节点下标为 i:

  1. 当 i == 0 时, 为根节点。
  2. 当 i >= 1 时, 父节点为 (i - 1) / 2;

size 就是元素的个数,从 1 开始计数。

下面就看一下怎么建立一个大顶堆:

将元素依次排到完全二叉树节点上,如左图所示:
在这里插入图片描述

  • int i = (size - 2) / 2 = 4 (思考这里为什么使用 size - 2 而不是size - 1)。 找到数组下标 4
    号,65 大于取其孩子,满足大顶堆的性质,不用交换。如下图:

在这里插入图片描述

  • 然后 i = i- 1;然后用 2 和其他孩子比较, 2 和 204 交换。交换之后 204 所在的子树满足大顶堆,如下图所示:

在这里插入图片描述

  • 54 和其他孩子比较,54 和 92 交换,此时92 所在子树满足大顶堆,如下图:

在这里插入图片描述

  • 继续,23 和其他孩子比较,23 和 204 交换,交换完之后,23 的子树却不满足了需要再调整如下图:
    在这里插入图片描述

  • 12 和 204 交换,然出现不平衡的情况,依次类推,知道根节点也满足要求就完毕了。
    在这里插入图片描述
    这样我们就建好了一个大顶堆,从图中可以看到,根元素是整个树中值最大的那个,二第二大和第三大就是其左右子树,具体那个更大是未知数,需要比较一下才知道。

另外,对于同一组数据,如果输入的序列不一样,最终的构造的树是否也会不一样呢?非常有可能,那么这样的树有什么意义呢?我们再往后面看看你,这里你已经理解怎么构建了对吧。

插入操作

从上面可以看到根节点和其左右节点是堆的老大老二老三,其他节点则是没有太明显的规律,那么如果要插入一个新的元素呢,该怎么办?直接说规则了:

将元素插入到保持其完全二叉树的最后一个位置,然后顺着这支一直向上调整,每前进一层就要保证其他子树都满足堆的要求,否则去调整子树,直到全部满足要求。

看一个例子,如下图,要插入 300 ,我们将其插入到 31的右孩子位置,然后不断向上爬, 31 < 300 ,所以两者需要交换,再向上 300 比 65 大,所以两者也要交换。最后 300 比根元素 204 大,两者也要交换,最后得到了新的堆。完整的过程如下:

在这里插入图片描述

删除操作

堆本身比较特殊,一般对堆中的数据进行操作都是针对堆顶的元素,即每次都从堆中获取得到最大或者最小值,其他得不关心,所以我们删除得时候,也删除堆顶元素。如果直接删掉堆顶,整个结果被破坏,群龙无首。所以实际策略是先将堆中最后一个元素,(假如为A)和堆顶元素进行替换,然后再删除堆中最后一个元素,之后再从跟开始逐步与之左右比较,谁得更大谁上位。然后A再继续与子树比较,如果有更大得继续交换,直到自己所在得子树也满足大顶堆得要求。

(上面得过程可以理解为:皇帝突然驾崩了,然后先找个顾命大臣维持局面,大臣先看看那个皇子更强大,谁就是老大。然后大臣就逐步隐退,找到属于自己得位置)
在这里插入图片描述
最后调整一下位置,满足堆得性质:

在这里插入图片描述
说了这么多,你觉得他得价值再哪里呢?价值在于大顶堆得根节点是整个树最大得那个,增加时会根据根得大小来决定要不要加,而删除操作只删除根元素。这个特征可以再很多场景下有巧妙得应用,后面得算法题目大多都是基于此得。

这里可能有很多人有疑问,感觉不管时插入还是删除,堆得操作都不简单,那么为什么还说堆得效率比较高呢?

这是因为堆元素得数量时有限制得,一般不用将所有得元素都放入堆里。后面题目中可以看到这些,在序列中找K大,则堆得大小就是k。如果K个链表合并,那么堆就是K。原理后面再展开详细展开。

说了这么多堆得性质了,我们来看看堆是怎么解决问题得。关于堆得问题,记住这里(我有秘法传于世间💕:

查找:找大用小,大的进;找小用大,小的进。
排序:升序用小,降序用大。

查找的方法就是:找 k 大, 则用小顶堆,后序的数据只有比根元素更大时才允许进入堆。如果找 k 小,则反过来。这我们后面接着分析。留个疑惑。


总结

提示:堆结构;堆的特性;堆的构造;堆的插入操作;堆的删除操作:


如果有帮助到你,请给题解点个赞和收藏,让更多的人看到 ~ ("▔□▔)/

如有不理解的地方,欢迎你在评论区给我留言,我都会逐一回复 ~

也欢迎你 关注我 ,喜欢交朋友,喜欢一起探讨问题。
在这里插入图片描述

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

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

相关文章

android 与 flutter 之间的通信

文章目录 前言集成 flutter 混合开发android 与 flutter 之间的通信总结 一、前言 因为flutter 具有跨平台的属性&#xff0c;既可以在android上跑&#xff0c;也能在ios 上跑&#xff0c;所以为了节约开发的成本&#xff0c;减少人力&#xff0c;势必就会用到它。然而已有的…

Matlab地理信息绘图—数据诊断

文章目录 数据诊断分析&#xff08;均值方差&#xff09;Matlab代码实现结果展示 数据诊断分析&#xff08;均值方差&#xff09; 均值方差检测是一种简单但有效的异常检测方法&#xff0c;主要基于样本的均值和方差的统计信息。该方法的核心思想是假设正常的样本点应该聚集在…

CNN-generated images are surprisingly easy to spot... for now

CNN-generated images are surprisingly easy to spot… for now----《目前CNN生成的图像非常容易被发现》 背景&#xff1a; 研究者们发现&#xff0c;仅仅对一种由CNN模型生成的图像进行训练的分类器&#xff0c;也可以检测许多其他模型生成的结果。由此提出这样的观点&#…

C语言中的自定义类型详解(结构体 + 枚举 + 联合(共用体))

文章目录 1. 结构体1.1 结构体的声明1.2 结构体成员的访问1.3 匿名结构体1.4 结构体的自引用1.5 结构体内存对齐&#xff08;计算结构体的大小&#xff09;1.6 结构体传参1.6.1 传值传递1.6.2 传址传递&#xff08;使用指针&#xff09; 2. 位段2.1 什么是位段&#xff1f;2.2 …

铅华洗尽,粉黛不施,人工智能AI基于ProPainter技术去除图片以及视频水印(Python3.10)

视频以及图片修复技术是一项具有挑战性的AI视觉任务&#xff0c;它涉及在视频或者图片序列中填补缺失或损坏的区域&#xff0c;同时保持空间和时间的连贯性。该技术在视频补全、对象移除、视频恢复等领域有广泛应用。近年来&#xff0c;两种突出的方案在视频修复中崭露头角&…

miRNA测序数据生信分析——第四讲,未知物种的生信分析实例

miRNA测序数据生信分析——第四讲&#xff0c;未知物种的生信分析实例 miRNA测序数据生信分析——第四讲&#xff0c;未知物种的生信分析实例1. 下载测序数据2. 原始数据质控——软件fastqc3. 注释tRNA和rRNA&#xff0c;使用Rfam数据库——软件blast&#xff0c;Rfam_statisti…

监控系列(六)prometheus监控DMHS操作步骤

一、监控的操作逻辑 给操作系统安装expect命令expect脚本执行dmhs_console脚本执行 cpt / exec 命令用脚本进行过滤字符串过滤dm_export读取脚本与当前日期作比较&#xff0c;然后返回差值 二、安装步骤 1. linux中Expect工具的安装及使用方法 https://blog.csdn.net/wangta…

mybatis拦截器源码分析

mybatis拦截器源码分析 拦截器简介 mybatis Plugins 拦截器由于Mybatis对数据库访问与操作进行了深度的封装,让我们应用开发效率大大提高,但是灵活度很差拦截器的作用:深度定制Mybatis的开发抛出一个需求 :获取Mybatis在开发过程中执行的SQL语句(执行什么操作获取那条SQL语句…

ChatGPT,AIGC 制作按年份选择的动态条形图

在数据分析与可视化中,条形图是用来进行对比分析,在正负条形图中都有哪些好处与优点呢? 正负条形图是一种常用的数据可视化方式,它的优点和好处包括: 1.明确展示:正负条形图可以清晰地显示出数据中的正负差异,使读者能直观地看出数据的变化和趋势。 2.直观比较:正负条…

苹果电脑其他内存怎么清理?

苹果电脑中的应用程序大部分是可以通过将其拖拽至废纸篓并倾倒来卸载的。但是部分程序在卸载后仍有残留文件&#xff0c;比如support文件和pref设置等文件的。小编今天介绍下苹果电脑清理内存怎么清理卸载残留以及好用的清理技巧分享。 一、苹果电脑清理内存怎么清理 苹果电脑…

简单实现一个todoList(上移、下移、置顶、置底)

演示 html部分 <!DOCTYPE html> <html> <head><title>表格示例</title> </head> <body><table border"1"><thead><tr><th>更新时间</th><th>操作</th></tr></thead…

thinkphp5.1 获取缓存cache(‘cache_name‘)特别慢,php 7.0 unserialize 特别慢

thinkphp5.1 获取缓存cache(‘cache_name’)特别慢&#xff0c;php 7.0 unserialize 特别慢 场景&#xff1a; 项目中大量使用了缓存&#xff0c;本地运行非常快&#xff0c;二三百毫秒&#xff0c;部署到服务器后 一个表格请求就七八秒&#xff0c;最初猜想是数据库查询慢&am…

KY258 日期累加

KY258 日期累加 int main() {int n 0; //样例个数cin >> n;//for循环处理n个样例for (int i 0; i < n; i){int y, m, d, num;int days[12] { 31,28,31,30,31,30,31,31,30,31,30,31 };//输入年月日 要加的天数cin >> y >> m >> d >>…

完整教程:Java+Vue+Websocket实现OSS文件上传进度条功能

引言 文件上传是Web应用开发中常见的需求之一&#xff0c;而实时显示文件上传的进度条可以提升用户体验。本教程将介绍如何使用Java后端和Vue前端实现文件上传进度条功能&#xff0c;借助阿里云的OSS服务进行文件上传。 技术栈 后端&#xff1a;Java、Spring Boot 、WebSock…

【Java学习之道】GUI开发的基本概念

引言 在这一章&#xff0c;我们将一起走进Java的图形用户界面&#xff08;GUI&#xff09;开发的世界。在你阅读完这篇文章后&#xff0c;你将能够了解什么是GUI&#xff0c;以及如何使用Java进行GUI的开发。 一、什么是GUI 首先&#xff0c;让我们来解答一个许多初学者都会…

AN基础工具——变形工具

【AN基础工具——变形工具】 基本使用方法&#xff1a;任意变形工具基础动画 本篇内容&#xff1a;学会使用变形工具 重点内容&#xff1a;变形工具 工 具&#xff1a;Adobe Animate 2022 基本使用方法&#xff1a; 任意变形工具 《任意变形工具&#xff08;快捷键Q&#xff0…

深度学习系列51:hugging face加速库optimum

1. 普通模型 Optimum是huggingface transformers库的一个扩展包&#xff0c;用来提升模型在指定硬件上的训练和推理性能。Optimum支持多种硬件&#xff0c;不同硬件下的安卓方式如下&#xff1a; 如果是国内安装的话&#xff0c;记得加上-i https://pypi.tuna.tsinghua.edu.c…

八大排序算法(含时间复杂度、空间复杂度、算法稳定性)

文章目录 八大排序算法(含时间复杂度、空间复杂度、算法稳定性)1、&#xff08;直接&#xff09;插入排序1.1、算法思想1.2、排序过程图解1.3、排序代码 2、希尔排序3、冒泡排序3.1、算法思想3.2、排序过程图解3.3、排序代码 4、&#xff08;简单&#xff09;选择排序4.1、算法…

Springcloud笔记(2)-Eureka服务注册中心

Eureka服务注册 Eureka作为一个微服务的治理中心&#xff0c;它是一个服务应用&#xff0c;可以接收其他服务的注册&#xff0c;也可以发现和治理服务实例。 服务治理中心是微服务&#xff08;分布式&#xff09;架构中最基础和最核心的功能组件&#xff0c;它主要对各个服务…

kafka生产者发送消息报错 Bootstrap broker localhost:9092 (id: -1 rack: null) disconnected

报这个错误是因为kafka里的配置要修改下 在config目录下 server.properties配置文件 这下发送消息就不会一直等待&#xff0c;就可以发送成功了