数据结构(8)-二叉堆

【数据结构】二叉堆一文详解,附demo 有时候也挺迷惑的,技术那么多,感觉学什么都来不及,又什么都得学,经常一看别人,哇,比你年轻比你厉害,然后自己emo一下又要鸡血模式,就挺无语的,但愿我们的坚持与努力都不白费吧,虽然开发可能不是一辈子的事,但但是干一天优秀一天,也是很有价值感的,加油共勉二叉堆(Binary Heap)是一种数据结构,用于。(Min Heap)和(Max Heap)。。二叉堆的关键特性是它提供了对堆中元素的快速访问、插入和删除操作,所有这些操作的时间复杂度都是 O(log n),其中 n 是堆中的元素数量。 阅读详情

二叉堆(binary heap)是一种特殊的堆,二叉堆是完全二叉树或者是近似完全二叉树。二叉堆满足堆特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子树和右子树都是一个二叉堆。
当父节点的键值总是大于或等于任何一个子节点的键值时该二叉堆被称为为“大顶堆”。当父节点的键值总是小于或等于任何一个子节点的键值时被称为为“小顶堆”。

一、基本概念

  • 堆有序:
    当一颗二叉树的每个节点都大于等于它的两个子节点或者每个节点都小于等于它的两个子节点时,它被称为堆有序。

  • 大顶堆:
    当一颗二叉树的每个节点都大于等于它的两个子节点时,这个堆被称为”大顶堆“,由大顶堆的性质可知,根节点就是这个堆中的最大值节点。

  • 小顶堆:
    当一颗二叉树的每个节点都小于等于它的两个子节点时,这个堆被称为”小顶堆“,由小顶堆的性质可知,根节点就是这个堆中的最小值节点。
    在这里插入图片描述

二、二叉堆表示法

如果我们使用指针来表示堆有序的二叉树,那么每个元素都需要三个指针来找到它的上下节点。但如果我们使用完全二叉树来表达二叉堆就会变得很方便:完全二叉树只用数组而不需要指针就可以表示出每个节点的位置。具体方式就是将二叉树的节点按照层级顺序放入数组中,根节点在位置1,它的子节点在位置2和3,而子节点的子节点则分别在位置4、 5、 6和7,以此类推。

所以

二叉堆是一组能够用堆有序的完全二叉树排序的元素,并且在数组中按照层级存储,而不使用数组的第一个位置。

2.1、确定节点位置

当我们使用数组来表示二叉堆,且不使用数组的0号索引时,我们可以很容易地找到第k个节点的父节点为[k/2],其左子节点和右子节点分别为[2*k]和[2*k+1],如下图
在这里插入图片描述

2.2、计算堆高度

一颗大小为N的完全二叉树的高度为[lgN],当N达到2的幂时树的高度会加1。

三、大顶堆的算法

我们使用长度为N+1的私有数组a[]来表示一个大小为N的堆,因为我们不会使用a[0],堆元素放置在a[1…N]中。堆的操作会首先进行一些简单的改动,打破堆的状态,然后通过遍历堆并且按照要求将堆的状态恢复,这被成为堆的有序化。

3.1、由下至上的堆有序化

如果堆的有序状态因为某个节点变得比它的父节点更大而被打破,那么这时应该对这个节点采用交换操作,来交换它和它的父节点的位置来恢复堆的有序。如果交换后,该节点仍比它的父节点大,那么此时应该继续重复交换操作,这被称为上浮(swim)。
在这里插入图片描述

3.2、由上至下的堆有序化

如果堆的有序状态因为某个节点变得比它的子节点更小而被打破,那么这时应该对这个节点采用交换操作,来交换它和它的子节点的位置来恢复堆的有序。如果交换后,该节点仍比它的子节点小,那么此时应该继续重复交换操作,这被称为下沉(sink)。

3.3、如何理解大顶堆的上浮和下沉

算法第四版这本书中对大顶堆做了一个很有意思的比喻:

如果我们把大顶堆想象成一个严密的黑社会组织,每个子节点都对应着一个下属,父节点则表示他的直接上级,那么这些操作就可以得到很有意思的解释。swim()表示一个很有能力的新人加入组织并被逐级提升(将能力不足的上级踩在脚下),知道他遇到一个更强的领导。sink()则类似于整个社团的领导退休并被外来者取代后,如果他的下属比他更厉害,他们的角色就会被互换,直到找到比他能力弱的下属为止。

四、算法具体实现

  • swim()
 public void swim(int k) {
        while (k > 1 && a[k] > a[k/2]) {
            //当k节点不为根节点且大于其父节点时上浮到父节点位置
            int temp = a[k];
            a[k] = a[k / 2];
            a[k / 2] = temp;
            //重新定位节点位置
            k = k / 2;
        }
    }
  • sink()
public void sink(int k) {
        while (2 * k <= size) {
            //目前j为左子节点
            int j = 2 * k;
            //比较左子节点和右子节点哪个大,将节点位置调整为大的子节点
            if (j < size && a[j] < a[j + 1]) {
                j++;
            }
            //j代表的子节点和父节点k比较,调整位置
            if (a[k] >= a[j]) {
                break;
            }
            //k < j
            int temp = a[k];
            a[j] = a[k];
            a[k] = temp;
            //重新定位k的位置
            k = j;
        }
    }

五、使用PriorityQueue实现小顶堆和大顶堆

//小顶堆
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k);
minHeap.offer(xxx);
minHeap.peek();
minHeap.poll();

//大顶堆
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k, new Comparator<Integer>() {
	@Override
	public int compare(Integer i1, Integer i2) {
		return i2 - i1;
	}
});
maxHeap.offer(xxx);
maxHeap.peek();
maxHeap.poll();
常用数据结构与算法:二叉堆(binary heap) 一:什么是二叉堆 二:二叉堆的实现  三:使用二叉堆的几个例子 一:什么是二叉堆 1.1:二叉堆简介       二叉堆故名思议是一种特殊的堆,二叉堆具有堆的性质(父节点的键值总是大于或等于(小于或等于)任何一个子节点的键值),二叉堆又具有二叉树的性质(二叉堆是完全二叉树或者是近似完全二叉树)。当父节点的键值大于或等于(小于或等于)它的每一个子节点的键值时我们称它为最大堆(最小堆 阅读详情

相关推荐

戴尔BIOS升级最新版本详细教程

戴尔BIOS升级是每位戴尔电脑用户都可能遇到的一项重要操作。通过升级BIOS,我们不仅能享受到戴尔公司不断推出的性能优化和新功能,还能有效修复已知的系统问题,提升电脑的稳定性和安全性。然而,许多用户在尝试升级BIOS时往往会遇到各种困难。为了帮助大家顺利完成这一操作,本文将详细介绍戴尔BIOS升级的步骤,确保每位用户都能轻松掌握。

nntxthml的博客 2826

[数据结构】二叉堆

一、什么是二叉堆 二、二叉堆的操作 1、插入节点 2、删除节点 3、构建而二叉堆 三、时间复杂度和空间复杂度 四、二叉堆的存储方式

weixin_45922730的博客 4274

宇树GO2-YOLOv5在Jetson Orin上的部署避坑实践

本文详细记录了在宇树GO2四足机器人搭载的Jetson Orin平台上部署YOLOv5目标检测模型的完整实践过程。文章重点分享了从ARM架构认知、网络连接解决方案、Archiconda环境搭建、PyTorch版本精准匹配到依赖安装与性能验证的核心步骤与避坑指南,旨在帮助开发者高效完成边缘计算环境下的算法部署。

app77的博客 670

二叉堆详解

一、什么是二叉堆 二叉堆是完全二叉树或者是近似完全二叉树,它分为两个类型: 最大堆 最小堆 最大堆是指任何一个父节点的值,都大于等于它左右孩子节点的值;最小堆是指任何一个父节点的值,都小于等于它左右孩子节点的值 二、二叉堆的自我调整 1.插入节点 我们以下面的最小堆为例,插入元素 新插入的元素为0,将新元素置于二叉堆最后一个位置 我们让新元素与它的父节点比较,如果新元素小于父节点,则与父节点交换位置,否则调整结束 新元素0与父节点5比较,0小于5,0与5交换位置 新元素0继续与父节点2比较,0小于

qq_35344198的博客 4164

[面试]SoC验证工程师面试常见问题(三)

SoC 验证工程师面试中,SystemVerilog、UVM 和 SystemC 的代码题目通常涵盖面向对象编程、约束随机化、UVM 组件设计、内存建模等主题。通过练习上述示例题目和理解关键点,你可以更好地应对现场编码环节。如果有具体的面试方向(如特定协议验证)或公司偏好,可以提供更多信息,我会进一步定制题目和答案。祝你面试顺利!

元直的博客 1643

Stata中介效应分析实战:从sgmediation安装到Sobel检验结果解读

本文提供了Stata中进行中介效应分析的完整实战指南,重点介绍了第三方命令sgmediation的安装、配置与使用。通过详细案例演示了如何运用Sobel检验分析变量间的间接效应,并深入解读检验结果,帮助研究者厘清自变量影响因变量的具体路径。文章还探讨了Sobel检验的原理、优缺点及结果报告规范,是进行实证研究的实用参考。

weixin_29197051的博客 631

常用数据结构之Heap(堆)

1.简介 接着上一篇数组和链表,我们今天来聊一聊堆。我们都知道在操作系统中有堆栈这一概念,学过java的同学都知道java虚拟机中也有堆栈这么一说。栈负责管理函数的上下文以及一些基本类型变量,这一块由系统管理。堆存放新建的对象,并且会将其地址指向栈中的一个引用变量。如果没有任何引用,对象就成为垃圾对象,最后由垃圾回收器回收。但是我这里要聊的并不是内存中的堆,内存一般使用链表的形式来管理。但数据结构中堆的概念,相当于一种优先队列。 2.堆的定义和性质 1.定义 ...

gaobing1993的博客 1252

IEDA激活码失效?教你5分钟快速续期的方法

本文针对IEDA激活码失效问题,提供了一套从快速应急到深度排查的完整解决方案。文章不仅详解了5分钟快速续期与清理缓存等应急方法,更深入剖析了授权机制、离线激活流程,并指导如何构建可持续的授权管理策略,帮助开发者彻底解决激活困扰,确保开发环境稳定。

a0b1c2d3的专栏 275

图解数据结构(8)——二叉堆

转载自http://www.cppblog.com/guogangj/archive/2009/10/29/99729.html 首先说说数据结构概念——堆(Heap),其实也没什么大不了,简单地说就是一种有序队列而已,普通的队列是先入先出,而二叉堆是:最小先出。 这不是很简单么?如果这个队列是用数组实现的话那用打擂台的方式从头到尾找一遍,把最小的拿出来不就行了?行啊,可是出队的操作是

Re_cover 1136

Unity技术开发干货 - 总目录

总目录 欢迎大家来到 passion 的《Unity技术开发干货》开始前博主先列出学习的大纲,同时也供大家学习参考,如果有什么问题,欢迎留言。 一.Unity基础: Unity基础-脚本生命周期 Unity基础-向量 Unity基础-寻路系统 Unity基础-物理系统 Unity基础-Mecanim动画系统 Unity基础-UGUI Unity基础-灯光 Unity-UGUI之Event System Unity-2018-粒子系统 Unity-协程入门 Unity-2D物理引擎、铰链、效应器 Unity-

TxNet 4266

【Bluetooth|蓝牙开发】二、蓝牙开发入门

蓝牙,是一种利用低功率无线电,支持设备短距离通信的无线电技术,能在包括移动电话、PDA、无线耳机、笔记本电脑、相关外设等众多设备之间进行无线信息交换,蓝牙工作在全球通用的2.4GHz ISM(即工业、科学、医学)频段,使用IEEE802.11协议。

Donge's Blog 1万+

【C++研发面试笔记】8. 基本数据结构-二叉堆

【C++研发面试笔记】8. 基本数据结构-二叉堆最大堆、最小堆分别指堆顶为最大或最小元素的堆,也叫大顶和小顶堆。堆是一种基本的抽象数据类型,一般用二叉树表示并且递归定义,堆顶为树的根,保证树或者子树的根永远比子节点大或者小。 堆的一个经典的实现是完全二叉树。这样实现的堆成为二叉堆。完全二叉树是增加了限定条件的二叉树。假设一个二叉树的深度为n。为了满足完全二叉树的要求,该二叉树的前n-1层必须填满,

tostq的专栏 950

深入理解Android音视频同步机制(三)NuPlayer的avsync逻辑

本文深入介绍了NuPlayer的avsync逻辑和原理

张晖的专栏 1万+

基于 Python 的数据结构与算法分析学习记录(6-8)—— 基于二叉堆的优先队列

优先级队列的作用就像一个队列,你可以通过从前面删除一个项目来出队。然而,在优先级队列中,队列中的项的逻辑顺序由它们的优先级确定。最高优先级项在队列的前面,最低优先级的项在后面。因此,当你将项排入优先级队列时,新项可能会一直移动到前面。实现优先级队列的经典方法是使用称为二叉堆的数据结构。二叉堆将允许我们在 O(logn) 中排队和取出队列。二叉堆是很有趣的研究,因为堆看起来很像一棵树,但是当我们实现它

HeatDeath的博客 661

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

每日总结[8] 20191016 数据结构复习-堆-二叉堆/比较器Comparable和Comparator

(1)头脑风暴:把我能想到的的先写下来。 堆一般用完全二叉树实现——二叉堆。 完全二叉树就是除了最后一层不满以外,其他层都需要是满的。靠左排。 完全二叉树可以使用数组存储。 如果每个根节点都不小于它的左右子树,那么这个堆是大顶堆/最大堆。 JVM中的堆存类的对象,数组对象。 操作系统的堆用链表实现。 堆有siftUp元素上浮,是指向堆添加元素时,鉴于数组,直接删除和插入都需要元素整体搬移,时间和空...

weixin_41750142的博客 245

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

PriorityBlockingQueue知识点

JDK1.8版本 特点 1.基于最小二叉堆实现的一个优先级队列 2.使用一把锁锁来实现线程安全,但是对于读写阻塞 3.无界队列,不支持插入null元素 4.因为是一个完全二叉树所以底层使用数组来存储 5.扩容的时候使用CAS来实现 主要方法 1.新增方法,add(E e),offer(E e)...

235

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

JavaScript二叉堆与优先队列:手写生产级PriorityQueue

优先队列(Priority Queue)是一种按优先级动态调度元素的基础数据结构,其核心实现常依赖二叉堆(Binary Heap)。二叉堆利用完全二叉树的数组映射特性,在插入、删除、获取最值等操作上实现O(log n)时间复杂度,显著优于排序数组的O(n log n)。它在前端调度(如React Scheduler)、实时消息队列、动画帧控制和Web Audio事件管理中被广泛采用。本文聚焦JavaScript工程实践,详解如何用原生数组实现MinHeap/MaxHeap,并封装支持add、poll、pee

weixin_33712987的博客 345

数据结构 — 二叉堆

二叉堆一、概述二、堆的两种类型1. 最大堆2. 最小堆三、代码实现 一、概述 二叉堆本质上是一种完全二叉树,二叉堆有两种类型: 最大堆 最小堆 完全二叉树:数据结构—完全二叉树 二、堆的两种类型 1. 最大堆 什么是最大堆呢?最大堆任何一个父节点的值,都大于等于它左右孩子节点的值。 2. 最小堆 什么是最小堆呢?最小堆任何一个父节点的值,都小于等于它左右孩子节点的值。 三、代码实现 ...

Elson的博客 604

【数据结构】【堆】二叉堆

二叉堆结构的特点 1.二叉堆提供的接口 添加元素 获取最大值 删除最大值 public interface Heap<E> { int size(); // 元素的数量 boolean isEmpty(); // 是否为空 void clear(); // 清空 void add(E element); // 添加元素 E get(); // 获得堆顶元素 E remove(); // 删除堆顶元素 E replace(E element); // 删除堆顶元素的同时插入一个

weixin_43589563的博客 830

【图解二叉堆】以后有面试官问你二叉堆,你就把这篇文章扔给他

二叉堆是一种应用很广的数据结构,今天,我们就来简单讲讲二叉堆。 什么是二叉堆? 二叉堆是一种特殊的堆。具有如下的特性: 具有完全二叉树的特性。 堆中的任何一个父节点的值都大于等于它左右孩子节点的值,或者都小于等于它左右孩子节点的值。 根据第二条特性,我们又可以把二叉堆分成两类: 1、最大堆:父节点的值大于等于左右孩子节点的值。 2、最小堆:父节点的值小于等于左右孩子节点的值。 我们把二叉堆...

帅地 3319
上一篇: Linux(6)-云服务器安全组和域名解析配置
下一篇: 数据结构(9)-优先队列
BoringRong
BoringRong 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 2万+粉丝 386原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值