首页 > 编程语言 >【数据结构与算法】如何构建最小堆

【数据结构与算法】如何构建最小堆

时间:2024-08-18 20:22:49浏览次数:11  
标签:heapq 元素 最小 插入 算法 构建 heap 数据结构 节点

最小堆的定义

最小堆,作为一种独特且重要的数据结构,它是一种特殊的二叉树。在这种二叉树中,有一个关键的规则:每一个父节点所存储的值,都必然小于或者等于其对应的子节点的值。这一规则确保了根节点总是承载着整个堆中的最小数值。

例如,下面这样一个简单的结构就是最小堆:

    1
  /   \
 3     2

在这个例子中,根节点的 1 毫无疑问是整个堆中数值最小的元素。

最小堆的表示

一般来说,最小堆是通过数组形式来表示。最小堆是完全二叉树,而对于一棵完全二叉树:

如果一个节点的编号为 i ,那么它的左子节点的编号为 2 * i + 1 ,右子节点的编号为 2 * i + 2

例如,节点 0 的左子节点编号为 2 * 0 + 1 = 1 ,右子节点编号为 2 * 0 + 2 = 2

节点 1 的左子节点编号为 2 * 1 + 1 = 3 ,右子节点编号为 2 * 1 + 2 = 4 ,以此类推。

这种编号规则使得在数组中表示完全二叉树时,可以方便地通过索引计算来快速找到节点的子节点,从而高效地进行最小堆的相关操作,如插入、删除等。

最小堆的操作

插入操作

当我们要将一个新元素插入到最小堆中时,首先会将这个元素添加在堆的末尾位置。随后,通过一系列细致的比较和交换操作,逐步将这个新元素向上调整,直至其处于一个合适的位置,从而确保最小堆的性质始终得以维持。

删除操作

在删除操作中,我们针对的是最小堆的根节点,因为它代表着整个堆中的最小值。执行删除操作时,会将堆中的最后一个元素移动到根节点的位置。然后通过比较找到最小值,并将其与堆的根节点交换。然后,重复这个过程,直到堆中的元素全部满足最小堆的性质。

示例

首先,假设我们给定一个特定的序列:

在这里插入图片描述

那么,其最小堆的构建过程会是这样:

在这里插入图片描述

需要特别留意的是,每次在将新的节点插入到堆的最后位置时,都必须与父节点进行严谨的比较操作,直至完全符合最小堆的性质要求。

然后我们删除一个元素
在这里插入图片描述

先将4移动到根节点,然后与两个子节点比较找到最小值

Python 内置的 heapq

在 Python 语言中,heapq 模块为我们提供了以下主要方法:

  1. heapq.heappush(heap, item) :此方法用于将 item 插入到 heap 当中,并且在插入过程中始终维持堆的固有性质。
  2. heapq.heappop(heap) :其功能是弹出并返回 heap 中的最小元素。
  3. heapq.heapify(heap) :能够将给定的列表 heap 直接转换为一个堆,而且是在原地进行修改。

依靠 heapq 模块的这些强大功能,我们能够迅速且高效地构建和操作最小堆。

比如:

import heapq

heap = [5, 2, 8, 1]
heapq.heapify(heap)  # 将列表转换为堆

heapq.heappush(heap, 3)  # 插入元素

print(heapq.heappop(heap))  # 弹出并返回最小元素

最小堆的应用

优先队列

在众多需要依据元素优先级来进行处理的场景当中,最小堆都能够发挥出显著的重要作用,从而成为构建优先级队列的理想之选。比如在复杂的任务调度场景里,任务往往被赋予不同的优先级。在这种情况下,具有最高优先级(也就是拥有最小的优先级值)的任务将会被优先安排处理。这一特性使得最小堆能够在这种需要精确排序和快速处理的环境中表现出色,极大地提高了任务处理的效率和准确性。

排序算法

以堆排序为例,其充分利用了最小堆所独有的特性,从而得以实现对数据的高效排序。堆排序的过程中,通过巧妙地构建和调整最小堆,能够以相对较少的操作次数和较低的时间复杂度完成对大量数据的排序工作。与其他常见的排序算法相比,堆排序在处理大规模数据时具有明显的优势,能够在较短的时间内获得准确的排序结果。

TOPK 问题

在面对 TOPK 问题时,可以精心维护一个设定了最大容量的最小堆。当堆中的元素数量达到最大容量时,将位于堆顶的元素弹出。与此同时,把新的元素插入到堆中。通过这种动态的调整和更新,能够确保在任何时刻,堆中都保存着当前最为关键的前 K 个元素。这一方法在处理大量数据并需要快速筛选出特定数量的重要元素时非常有效,极大地提高了数据处理的效率和针对性。

图算法

在某些复杂的图算法中,例如迪杰斯特拉算法用于求解最短路径时,最小堆能够发挥关键作用。它能够从众多尚未访问的节点当中,精准且高效地挑选出距离源点最近的节点。这一特性使得在处理大规模的图数据时,可以快速找到最优的路径或者解决方案,显著减少了计算时间和资源消耗。


2024/08/18

标签:heapq,元素,最小,插入,算法,构建,heap,数据结构,节点
From: https://blog.csdn.net/longforone/article/details/141304321

相关文章

  • 【优化算法】遗传算法及加速遗传算法(超详细更新中)
    一·遗传算法基本概念GeneticAlgorithm,GA:起源于对生物系统进行的计算机模拟研究。最早是由美国密歇根大学Holland教授及其学生于20世纪60年代末到70年代初提出。是借鉴孟德尔遗传学说模仿生物进化发展起来的随机全局搜索和优化方法。本质是高效,并行,全局搜索的方法。遗传算......
  • 粒子群算法初步与在求函数最值上的应用
    粒子群算法是一种优化算法,也是一种启发式算法。按照预定的策略实行搜索,在搜索过程中获取的中间信息不用来改进策略,称为盲目搜索;反之,如果利用了中间信息来改进搜索策略则称为启发式搜索。蒙特卡罗模拟用来求解优化问题就是盲目搜索,还有大家熟悉的枚举法也是盲目搜索。因为其并没有......
  • 【卡车-多无人机送货】基于健康距离平衡的进化算法的卡车-多无人机送货系统研究(Matlab
       ......
  • 虹软科技25届校招笔试算法 A卷
    目录1.第一题2.第二题3.论述题⏰时间:2024/08/18......
  • 离线算法 莫队算法进阶
    前算是把之前的坑填一填吧。这篇文章主要包含带修莫队,二维莫队等莫队算法的进阶应用,观看前请确保您已经熟练掌握了基本的莫队算法,不会的可以戳这里。带修莫队众所周知,普通莫队是不支持修改的,因为我们为了得到更优的时间复杂度,需要将每次询问离线下来,打乱顺序。不过我们也......
  • CORDIC算法解释及FPGA实现(圆坐标系)
    CORDIC算法原理阐述CORDIC(CoordinateRotationDigitalComputer)算法,即坐标旋转数字计算方法,是J.D.Volder1于1959年首次提出,主要用于三角函数、双曲线、指数、对数的计算。伪旋转在笛卡尔坐标平面(下方左图)由\(({x_1},{y_1})\)旋转θ角度至\(({x_2},{y_2})\)得到:\(({\hat......
  • 2024年图像配准最新算法EfficientLoFTR(cvpr2024) 【补丁For 双鱼眼全景视频拼接】
    前言对于双鱼眼全景拼接这个项目来说,单应性矩阵是最重要的一环。单应性矩阵中它既包含了相机的内参,也包含了相机的外参。因此就算你的相机没有特别好的定位,也能通过好的单应性矩阵救回来。2024最新DNN配准算法在双鱼眼相机拼接中,特征点检测与匹配是影响单应性矩阵最......
  • 嵌入式中PID算法分析与实现详解
        看起来PID高大尚,先被别人唬住,后被公式唬住,由于大多数人高数一点都不会或者遗忘,所以再一看公式,简直吓死。    直接从网上找了PID相关公式截图如下。    了解了很浅的原理后,结果公式看不懂,不懂含义,所以最终没有透彻。我这里先对公式进行剖析,公式理解明白......
  • 22.给定 n 对括号,实现一个算法生成所有可能的正确匹配的括号组合
    22.GenerateParentheses题目给定n对括号,编写一个函数生成所有可能的正确匹配的括号组合。例如,当n=3时,可能的组合集合为:["((()))","(()())","(())()","()(())","()()()"]题目大意给出n代表生成括号的对数,请你写出一个函数,使其能够生成所有......
  • 17.实现一个算法根据电话按键上的数字和字母的映射关系,输入一个或多个数字返回所有它
    17.LetterCombinationsofaPhoneNumber题目Givenastringcontainingdigitsfrom2-9inclusive,returnallpossiblelettercombinationsthatthenumbercouldrepresent.Amappingofdigittoletters(justlikeonthetelephonebuttons)isgivenbelo......