堆排序

  • 什么是堆排序
  • 操作步骤
  • 时间复杂度
  • 特点

什么是堆排序

堆排序利用这种数据结构来进行排序。基本思路是:先把所有数据放进堆里构建最大堆,然后不断取出最大值放在数组末尾。

操作步骤

5 2 7 3 6 1 4 为例:

第 1 步:将所有数据存入堆,构建最大堆(子结点小于父结点,最大值在根)

      7          ← 最大值在根结点
    /   \
   6     5
  / \   /
 2   3 1 4

第 2 步:取出根结点(最大值 7),放在数组最右边

  堆:                数组:  _ _ _ _ _ _ [7]
      6
    /   \
   4     5
  / \   /
 2   3 1

第 3 步:重构堆,取出新的最大值 6,放在右数第 2 个位置

  堆:                数组:  _ _ _ _ _ [6 7]
      5
    /   \
   4     1
  / \
 2   3

继续重复:每次取出最大值,放在数组右边的下一个位置

取出 5 →  _ _ _ _ [5 6 7]
取出 4 →  _ _ _ [4 5 6 7]
取出 3 →  _ _ [3 4 5 6 7]
取出 2 →  _ [2 3 4 5 6 7]
取出 1 →  [1 2 3 4 5 6 7]

排序完成!

时间复杂度

项目 时间复杂度 说明
构建堆 O(n log n) n 个数据逐个插入堆
取出 + 重构 O(n log n) 每次取出后重构 O(log n),共 n 次
总计 O(n log n)

堆排序的时间复杂度为 O(n log n),比冒泡、选择、插入排序的 O(n²) 都快。

特点

  • 时间复杂度稳定为 O(n log n),没有最坏情况退化
  • 原地排序:实际上是将堆嵌入到数组中,不需要额外空间
  • 不稳定排序
  • 由于使用堆这种较复杂的数据结构,实现难度较大
  • 实际运行中常数因子较大,通常比快速排序慢

小结

  • 堆排序利用堆每次取最大值,反序放入数组
  • 时间复杂度 O(n log n),稳定高效
  • 原地排序,但不稳定
  • 适合需要保证最坏情况性能的场景