1. 堆:不只是数据结构,更是排序的“发动机”
如果你对排序算法的印象还停留在冒泡排序的“两两交换”和快速排序的“分而治之”,那么今天我们来聊一个有点特别,但效率极高的家伙——堆排序。我第一次接触堆排序时,觉得它有点“绕”,既要理解“堆”这个数据结构,又要搞懂怎么用它来排序。但真正弄明白后,我发现它简直是处理大数据排序的利器,尤其是在需要不断找出最大或最小元素的场景里,比如游戏里的排行榜实时更新、操作系统的任务优先级调度,它的表现非常稳定。
那么,堆到底是什么呢?你可以把它想象成一棵特殊的完全二叉树。这棵树有个严格的“家规”:每个“父亲”节点都必须比它的两个“孩子”节点大(或者小)。如果父亲总是最大的,这叫大根堆(或大顶堆),堆顶(树根)就是整个堆里的最大值;反过来,如果父亲总是最小的,这叫小根堆(或小顶堆),堆顶就是最小值。这个“家规”保证了堆的核心秩序:无论堆里的元素怎么变动,堆顶元素始终是当前所有元素中的极值。这个特性,正是堆排序高效的关键所在。
为什么说它特殊呢?因为它虽然逻辑上是一棵树,但在我们写代码时,却用数组来存储。这充分利用了完全二叉树的特性:假设父亲节点在数组中的下标是 i,那么它的左孩子下标就是 2*i + 1,右孩子是 2*i + 2。反过来,一个下标为 j 的节点,它的父亲节点下标就是 (j-1) / 2(整数除法)。这种映射关系非常简洁,让我们可以抛开复杂的指针,直接用数组下标就在树形结构和线性存储之间自由穿梭。理解了堆的这个底层物理结构,后面的调整和排序算法就清晰多了。
2. 堆的基石:向下与向上调整算法
堆之所以能维持秩序,全靠两个核心操作:向下调整和向上调整。它们是堆所有功能,包括建堆和排序的“基本功”。咱们先打个比方:假设一个公司的部门(一个子树)原本管理良好(符合堆的性质),但部门经理(父节点)突然换人了,能力可能不如手下(子节点),这时就需要从这位新经理开始向下考察调整,这就是向下调整。而当一个新员工(新节点)加入部门最底层,能力可能很强,就需要逐级向上汇报、调整位置,这就是向上调整。
2.1 向下调整算法:让“不合格”的父节点下沉
向下调整算法的目标是:在一个左右子树都已经满足堆性质的前提下,如果根节点破坏了堆的性质,就通过调整让它重新成为一个堆。这个前提很重要,意味着调整是从局部不满足的点开始的修复过程。
它的核心思想是“优胜劣汰,向下渗透”。以建小根堆为例,算法步骤如下:
- 从指定的父节点
parent开始,比较它和它的左右孩子。 - 选出左右孩子中更小的那一个,记作
child。 - 如果这个更小的孩子
child比父亲parent还小,那就说明父亲“不合格”,需要交换它们俩的值。这样一来,小的往上走,大的往

3万+

被折叠的 条评论
为什么被折叠?



