商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 如何利用数组实现基于数组的最大堆逻辑并实战提取变量最大值

如何利用数组实现基于数组的最大堆逻辑并实战提取变量最大值

  发布于2026-05-20 阅读(0)

扫一扫,手机访问

用数组实现最大堆,本质上是在一维空间里模拟一棵完全二叉树,并通过一套简单的索引计算规则,维持“父节点永远大于等于子节点”的核心秩序。这种结构的设计初衷,并非为了在静态数据里找一次最大值——那种情况用 max() 函数就够了。它的真正威力,在于能动态、高效地维护一个持续变化的数据集,让你能以极快的速度反复获取当前的最大值。无论是实时更新的排行榜、优先任务队列,还是流式数据中的峰值监控,数组堆都是背后的经典引擎。

如何利用数组实现基于数组的最大堆逻辑并实战提取变量最大值

数组下标与父子节点的对应关系

一切操作都建立在索引映射这个“地基”之上。假设数组索引从0开始(这也是PHP等多数语言的默认方式),那么对于数组中任意位置 i 的元素,其家庭成员的位置可以通过固定公式瞬间定位:

  • 父节点索引 = (int)(($i - 1) / 2)
  • 左子节点索引 = $i * 2 + 1
  • 右子节点索引 = $i * 2 + 2

举个例子就清楚了:索引0是根节点,它的左孩子是1,右孩子是2。索引3的父节点是 (3-1)/2 = 1;索引4的父节点同样是 (4-1)/2 = 1(整除结果)。这套关系必须烂熟于心,后续所有的“上浮”和“下沉”调整,都靠它来驱动。

插入新元素:先追加,再上浮调整

当有新成员要加入时,策略很直接:先把它放到数组末尾,再视情况把它“托举”到合适的高度。因为新元素可能比它的父节点大,这就破坏了堆序性,需要一次“上浮”操作来修复。

  • 第一步,执行 array_push($heap, $value),将新值放到堆尾。
  • 第二步,记下它的位置:$i = count($heap) - 1
  • 第三步,开始循环“攀爬”:只要满足 $heap[$i] > $heap[(int)(($i-1)/2)](即比父节点大),就与父节点交换位置,并将当前位置 $i 更新为父节点的索引。
  • 循环直到它到达根节点(索引0),或者不再大于其父节点时停止。

来看个实例:向最大堆 [50, 30, 40, 10, 20, 35] 中插入15。追加后数组变为 [50, 30, 40, 10, 20, 35, 15]。新元素15位于索引6,其父节点是索引2(值为40)。由于15小于40,不满足交换条件,插入过程就此完成,堆序性依然完好。

提取并删除最大值:取堆顶、补末尾、再下沉

最大值永远稳坐堆顶(索引0)。删除它时有个小技巧:不能简单地将它从数组中移除,那样会破坏完全二叉树的结构。正确的做法是“李代桃僵”。

  • 首先,取出最大值:$max = $heap[0]
  • 接着,将数组的最后一个元素移到堆顶:$heap[0] = array_pop($heap)
  • 最后,关键的一步来了:这个被推到顶端的“末位元素”很可能德不配位,需要执行“下沉”操作(siftDown(0)),让它找到自己真正该待的位置。

下沉的逻辑是:比较当前节点与其左右子节点中较大的那一个。如果当前节点比那个子节点小,就交换它们的位置,然后继续从新的子节点位置向下比较。这个过程一直持续到当前节点大于等于它的所有子节点,或者已经沉到底成为叶子节点为止。

实现时需注意边界:左子索引 $left = $i * 2 + 1 必须小于当前堆的大小,右子索引同理。如果只有左子节点,那就只和左子比较。

实战:动态获取数据流中的最大值

让我们设想一个实际场景:你正在监控一系列实时传入的温度读数,需要随时知道当前最高的温度值,并且这个数据集会不断新增,偶尔还需要移除无效的峰值。

  • 初始化$tempHeap = []; 创建一个空堆。
  • 持续插入insert($tempHeap, 28); insert($tempHeap, 32); insert($tempHeap, 29); … 每个新读数都通过插入操作入堆。
  • 瞬时取最大值:任何时候,当前最高温就是 $tempHeap[0] ?? null;。这是O(1)时间复杂度,无需遍历整个数组。
  • 移除最大值后:如果某个最高值被判定为无效需要剔除,调用 $removed = deleteMax($tempHeap);。堆会自动内部重组,之后 $tempHeap[0] 给出的就是新的最大值。

与每次调用 max($array) 都需要全量扫描O(n)相比,堆结构在频繁增删的场景下优势巨大。它将“获取最大值”的成本锁定在常数时间,而“删除并重组”的成本也仅是对数级别,堪称管理动态极值问题的利器。

本文转载于:https://www.php.cn/faq/2471851.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注