算法通关村第十四关—堆结构(青铜)

news2024/12/24 22:16:23

        堆结构

一、堆的概念和特征

 堆是将一组数据按照完全二叉树的存储顺序,将数据存储在一个一维数组中的结构。堆有两种结构,一种称为大顶堆,一种称为小顶堆,如下图。
1.小顶堆:任意节点的值均小于等于它的左右孩子,并且最小的值位于堆顶,即根节点处
2.大顶堆:任意节点的值均大于等于它的左右孩子,并且最大的值位于堆顶,即根节点处。
 有些地方也叫大根堆、小根堆,或者最大堆、最小堆。大和小的特征等都是类似的。
image.png

二、堆的构造过程

这里先假设一个节点的下标为:
1、当i=0时,为根节点。
2、当i>=1时,父节点为(i-1)/2。
size就是元素的个数,从1开始计数。

下面就看一下如何建立一个大堆:
将元素依次排到完全二叉树节点上去,如下左图所示。
a.int i = (size-2)/2 = 4(思考一下这里为什么是size-2而不是size-1)。找到数组中的4号下标。
65大于其孩子,满足大堆性质,所以不用交换。如下右图
image.png
b.然后i=i-1;然后用2和其孩子比较,2和204交换。交换之后204所在的子树满足大堆,如下左图。
c.54和其孩子比较,54和92交换。此时92所在子树满足大堆,如下右图。
image.png
d.继续,23和其孩子比较,23和204交换,交换完之后,23的子树却不满足了,所以还需调整它的子树。如下两图所示。
image.png
e.12和204交换,仍然出现不平衡衡的情况,以此类推,直到根节点也满足要求就完毕了
image.png
 这样我们就建好了一个大顶堆,从图中可以看到,根元素是整个树中值最大的那个,而第二大和第三大就是其左右子树,具体是哪个更大则是未知的,需要比较一下才知道。

三、插入操作

 从上面可以看到根节点和其左右子节点是堆里的老大老二和老三,其他结点则没有太明显的规律,那如果要插入一个新元素,该怎么做呢?直接说规则,将元素插入到保持其为完全二叉树的最后一个位置,然后顺着这条支路一直向上调整,每前进一层就要保证其子树都满足堆否则测就去处理子树,直到完全满足要求。
 看一个例子,如下图,要插入300,我们将其插入到31的右孩子位置,然后不断向上爬,31<300,所以两者要交换,再向上发现300比65大,所以两者要交换。最后300比根元素204大,两者也交换。最后就得到了新的堆。完整过程如下所示:
image.png

四、删除操作

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

总结

 堆的价值就在于大顶堆的根节点是整个树最大的那个,增加时会根据根的大小来决定要不要加,而删除操作只删除根元素。这个特征可以在很多场景下有奇妙的应用,后面的算法题全都基于这一点。
 这里可能有些人还有疑问,感觉不管插入还是删除,堆的操作都不简单,那为什么还说堆的效率比较高呢?
 这是因为堆元素的数量是有限制的,一般不用将所有的元素都放到堆里。后面题目中可以看到,在序列中找K大,则堆的大小就是K。如果K个链表合并,那么堆就是K。原理后面详细展开。
 关于堆的问题,记住口诀:

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

 查找的口诀解释一下就是:是找K大,则用小堆,后续数据只有比根元素更大时才允许进入堆。如果是找K小,则对应反过来。

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

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

相关文章

android 新版studio gradle 里面没有offline 勾选项

studio 右边 gradle 上面有个图标可以点击切换

宏基因组学中基于Kraken2、Blast、ViPhOG和VirSorter等工具分析病毒组的详细流程,包括数据预处理、病毒序列检测、分类和功能注释等步骤

宏基因组学中分析病毒组的详细流程&#xff0c;包括数据预处理、病毒序列检测、分类和功能注释等步骤。 示例代码使用了常用的生物信息学工具&#xff0c;如Kraken2、Blast、ViPhOG和VirSorter等。 1. 数据预处理 质量控制&#xff1a; 使用FastQC进行原始测序数据的质量检查…

机器视觉:AI赋能缺陷检测,铸就芯片产品的大算力与高能效

导言&#xff1a;近年来&#xff0c;国内芯片行业快速发展&#xff0c;市场对芯片需求的不断增大&#xff0c;芯片的缺陷检测压力也越来越大。芯片产品在生产制造过程中&#xff0c;需要经历数道工序&#xff0c;每个生产环节的材料、环境、工艺参数等都有可能造成产品缺陷。不…

低代码:万事俱备,就差一个程序员

前言 低代码技术&#xff0c;作为当前软件开发领域的一颗新星&#xff0c;正在逐渐改变着传统编程的面貌。其核心特点鲜明且富有创新性&#xff0c;如通过直观的拖拽组件来进行软件开发&#xff0c;这种方式极大地降低了编程的复杂性。可视化编程则是将复杂的代码逻辑转化为图…

js 图片 手动上传,并回显

效果展示&#xff1a; 代码&#xff1a; <label for"avatarUpload"><div><img v-if"avatatImageUrl" :src"avatatImageUrl" class"avatar"><img v-else src"../../assets/images/account/avatar-upload.png…

20231221将NanoPC-T4(RK3399)开发板适配Android12的挖掘机并打开AP6398SV

20231221将NanoPC-T4(RK3399)开发板适配Android12的挖掘机并打开AP6398SV 2023/12/21 17:46 SDK使用&#xff1a;rk356x_android12_220722.tgz android12-rk3588-new_20221229_1732toybrick.tgz【TB3588X】 1、【必须更换AP6398SV征集的驱动程序&#xff01;】 Z:\3TB\91rk_an…

Elasticsearch 性能调优基础知识

Elastic Stack 已成为监控任何环境或应用程序的实际解决方案。 从日志、指标和正常运行时间到性能监控甚至安全&#xff0c;Elastic Stack 已成为满足几乎所有监控需求的一体化解决方案。 Elasticsearch 通过提供强大的分析引擎来处理任何类型的数据&#xff0c;成为这方面的基…

Vuex的学习-3

基于Vuex的案例todos&#xff0c;篇幅有点长&#xff0c;可以根据目录将会的地方可以跳过 初始化项目 1.通过vue ui 命令打开可视化面板&#xff0c;创建新项目 2.安装vuex依赖包 3.实现Todos基本布局 课程代码在此&#xff0c;直接复制即可 main.js import Vue from vue …

Seata中AT模式的实现原理02-RM分支事务提交

前言 RM是资源的管理者 处理分支事务的开启和提交回滚 当TM注册完全局事务之后进行分支事务的提交 RM一阶段处理本地事务&#xff0c;主要是在DataSource、Connection、Statement上做文章。 DataSource 创建 项目启动的时候SeataAutoDataSourceProxyCreator为所有DataSource…

通讯录应用程序开发指南

目录 一、前言 二、构建通讯录应用程序 2.1通讯录框架 (1)打印菜单 (2) 联系人信息的声明 (3)创建通讯录 (4)初始化通讯录 2.2功能实现 (1)增加联系人 (2)显示联系人 (3)删除联系人 (4)查找联系人 (5)修改联系人 (6)排序联系人 三、通讯录的优化 3.1 文件存储 …

RUST与RUSTful简介

RUST与RUSTful 1、背景2、RUST的起源3、RUST与RUSTful4、总结 1、背景 随着互联网&#xff08;Internet&#xff09;的发展&#xff0c;越来越多的人开始意识到&#xff0c;网站即软件&#xff0c;而且是一种新型的软件。这种"互联网软件"采用客户端/服务器&#xff…

el-table设置默认选中报错_this.$refs.singleTable.toggleAllSelection is not a function

直接使用以下的方法&#xff0c;报错信息是_this.$refs.singleTable.toggleAllSelection is not a function this.$refs.singleTable.toggleAllSelection()看了网上的解决方法&#xff0c;加了this.$nextTick,代码如下&#xff0c;但还是报错Error in nextTick: "TypeErr…

ubuntu部署llama2-chinese

ubuntu上安装cuda见之前的blog&#xff0c;已安装cuda12&#xff0c;使用nvcc-V 下载llama2-chinese&#xff1a;GitHub - FlagAlpha/Llama2-Chinese: Llama中文社区&#xff0c;最好的中文Llama大模型&#xff0c;完全开源可商用 conda create -n llamachinese python3.10 pi…

构建高效的研发管理体系

目录 一、什么是研发管理体系 二、研发管理体系有哪些 1、 基于CMMI的研发体系 ​2、基于IPD的研发体系 3、 基于敏捷模式的研发体系 三、研发管理的痛点 四、如何构建高效的研发管理体系 一、什么是研发管理体系 研发管理就是在研发体系结构设计的基础之上&#xff0…

[网络安全]在win2000虚拟机上创建隐藏账户

目录 1.winR->cmd->regedt32 2.新建账号&#xff0c;例如HiddenAccount$($表示在命令行下不现实此用户&#xff09; 3.winR->cmd->regedit 3.将HiddenAccount$删掉 4.最后一步 手工创建隐藏账户 1.你需要一台win2000 2.winR->cmd->regedt32 增加HEY_LOAC…

3A服务器 (hcia)

原理 认证&#xff1a;验证用户是否可以获得网络访问权。 授权&#xff1a;授权用户可以使用哪些服务。 计费&#xff1a;记录用户使用网络资源的情况 实验 步骤 1.配置ip地址 2.配置认证服务器 aaa authentication-scheme datacom&#xff08;认证服务器名字&#xf…

21 Vue3中使用v-for遍历对象数组

概述 使用v-for遍历对象数组在真实的开发中也属于非常常见的用法&#xff0c;需要重点掌握。 因为目前流行的是前后端分离开发&#xff0c;在前后端分离开发中&#xff0c;最常需要处理的就是对象数组类型的数据了。 比如&#xff0c;将员工信息渲染到表格中。 这节课我们就…

如何建立一套完整的私域运营体系?

所有人都告诉你&#xff0c;今年必须做私域&#xff0c;但从没有人说清楚怎么做私域。你以为做私域就像瑞星咖啡一样&#xff0c;随便拉个群、发发券就能年入100个小目标。或者你认为最后还是微商最有效&#xff0c;每天狂刷100条朋友圈。但这样的私域一定活不过30天。因为没有…

回顾丨2023 SpeechHome 第三届语音技术研讨会

下面是整体会议的内容回顾&#xff1a; 18日线上直播回顾 18日上午9:30&#xff0c;AISHELL & SpeechHome CEO卜辉宣布研讨会开始&#xff0c;并简要介绍本次研讨会的筹备情况以及报告内容。随后&#xff0c;CCF语音对话与听觉专委会副主任、清华大学教授郑方&#xff0c…

oracle定位造成卡顿的SQL语句

先查询阻塞的会话号 select event,machine,sql_id,program,blocking_session from dba_hist_active_sess_history where SAMPLE_TIME between TO_TIMESTAMP (2021-08-25 15:25:00, YYYY-MM-DD HH24:MI:SS) and TO_TIMESTAMP (2021-08-25 15:30:00, YYYY-MM-DD HH24:MI:SS) and …