堆排序(Heap Sort)是一种基于堆的数据结构的排序算法,具有 O(n log n) 的时间复杂度,适用于大规模数据的排序。
堆排序流程(以最大堆为例)
最大堆的特点是:父节点的值始终大于等于子节点的值,这样堆顶(根节点)始终是最大值。
1. 构建最大堆
- 从最后一个非叶子节点开始,向上调整,使整个数组满足最大堆的性质。
- 叶子节点天然是堆,因此我们只需调整内部节点。
2. 交换堆顶元素与末尾元素
- 堆顶元素(最大值)与最后一个元素交换,使最大值移至数组末尾。
- 这样,当前数组的最后一部分变为有序部分。
3. 重新调整剩余元素为最大堆
- 交换后,根节点可能不满足堆性质,因此对新的根节点向下调整(heapify),恢复最大堆。
- 继续重复步骤 2 和 3,直到堆中只剩下一个元素,排序完成。
示例
假设对数组 [4, 10, 3, 5, 1]
进行堆排序:
构建最大堆
初始数组:
4
/ \
10 3
/ \
5 1
调整成最大堆:
10
/ \
5 3
/ \
4 1
排序过程
- 交换
10
和1
(最大值放到末尾):
1, 5, 3, 4, (10)
- 调整剩余部分为最大堆(
5
变为新根,调整后5, 4, 3, 1
):
5, 4, 3, 1, (10)
- 交换
5
和1
:
1, 4, 3, (5, 10)
- 调整剩余部分为最大堆(
4
变为新根,调整后4, 1, 3
):
4, 1, 3, (5, 10)
- 交换
4
和3
:
3, 1, (4, 5, 10)
- 调整剩余部分为最大堆(
3
变为新根,无需调整):
3, 1, (4, 5, 10)
- 交换
3
和1
:
1, (3, 4, 5, 10)
- 调整剩余部分为最大堆(只剩
1
,无需调整):
(1, 3, 4, 5, 10)
最终结果:升序 [1, 3, 4, 5, 10]
时间复杂度
- 构建最大堆:O(n)
- 每次取出最大值并调整堆:O(log n),共进行 n-1 次
- 总时间复杂度:O(n log n)
总结
堆排序是一种不稳定但原地排序算法,适用于大规模数据的排序,尤其适合需要动态获取最大(或最小)值的场景。