数智应用帮
柔彩主题三 · 更轻盈的阅读体验

堆排序方法讲解:从原理到代码实现

发布时间:2026-01-21 19:20:47 阅读:221 次

排序是什么?

你有没有遇到过这种情况:手头有一堆待办事项,但不知道先处理哪个。如果每次都能快速找到最紧急的那条,效率就会高很多。堆排序的逻辑就和这个类似——它利用“堆”这种数据结构,总能快速定位最大或最小的元素,然后依次整理整个序列。

堆排序是一种基于比较的排序算法,它把数组看成一个完全二叉树,并通过维护“大顶堆”或“小顶堆”的性质来完成排序。最终结果要么从小到大,要么从大到小,取决于你用哪种堆。

堆的结构特点

堆本质上是一个数组,只是我们把它想象成一棵完全二叉树。父节点和子节点之间有固定的下标关系:

  • 父节点 i 的左孩子是 2*i+1
  • 父节点 i 的右孩子是 2*i+2
  • 任意节点 i 的父节点是 (i-1)/2(向下取整)

所谓大顶堆,就是每个父节点都大于等于它的子节点;小顶堆则相反。排序时通常用大顶堆来实现升序排列。

堆排序的三个关键步骤

第一步:构建初始大顶堆。从最后一个非叶子节点开始,向前逐个调整,确保每个子树都满足大顶堆的性质。

第二步:将堆顶(最大值)与末尾元素交换,此时最大值就到了正确位置。然后把剩下的元素重新调整成大顶堆。

第三步:重复第二步,直到只剩一个元素。整个数组也就有序了。

代码实现不难懂

下面是一个用 Python 实现的堆排序例子,逻辑清晰,适合理解核心思想:

def heapify(arr, n, i):
largest = i
left = 2 * i + 1
right = 2 * i + 2

if left < n and arr[left] > arr[largest]:
largest = left

if right < n and arr[right] > arr[largest]:
largest = right

if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)

def heap_sort(arr):
n = len(arr)

for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)

for i in range(n - 1, 0, -1):
arr[0], arr[i] = arr[i], arr[0]
heapify(arr, i, 0)

这段代码里的 heapify 函数负责调整单个节点,让它及其子树满足大顶堆要求。heap_sort 先建堆,再不断把最大值移到末尾。

为什么选堆排序?

在实际应用中,堆排序的优势在于时间稳定。不管数据怎么分布,最坏、平均时间复杂度都是 O(n log n),不像快排可能退化到 O(n²)。而且它原地排序,空间只用 O(1),对内存紧张的环境挺友好。

比如你在路由器后台写了个日志分析模块,需要按时间戳排序几千条记录,又不想引入太多依赖,堆排序就是个可靠选择。虽然不如 Python 内置的 sorted() 快,但理解它能帮你更清楚底层发生了什么。

掌握堆排序不只是为了写排序函数,更重要的是理解“堆”这种结构在任务调度、优先队列等场景中的广泛应用。下次看到“优先处理紧急任务”,不妨想想是不是可以用堆来实现。