什么是堆
堆是一种特殊的树,需要满足两点要求:
- 是完全二叉树
- 每个节点都大于等于(或小于等于)其左右子节点
注:每个节点都大于等于其左右子节点的叫做大顶堆,每个节点都小于等于其左右子节点的叫做小顶堆。
堆的操作
- 往堆中插入一个元素
实现:插入堆的末尾后进行从下往上的堆化 - 删除堆顶元素
实现:删除堆顶元素后,将末尾元素放至堆顶,然后进行从上往下的堆化
基于堆实现排序
- 建堆
建立堆时间复杂度为 O ( n ) O(n) O(n) - 排序
- 将堆顶元素放到末尾,剩余元素进行堆化,接着将堆顶元素放到剩余元素的末尾,如此迭代至剩余元素只有一个元素为止。
- 排序的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)
堆排序与快速排序比较
1.时间、空间复杂度与稳定性
- 两者的平均时间复杂度都是 O ( n l o g n ) O(nlogn) O(nlogn),且快速排序在最坏情况下时间复杂度为 O ( n 2 ) O(n^2) O(n2)。
- 空间复杂度均为 O ( 1 ) O(1) O(1)
- 快速排序为稳定排序,堆排序为非稳定排序。
2.数据访问方式
- 快速排序的数据是顺序访问的。而堆排序在堆化时的数据是跳着访问的。这样对CPU缓存是不友好的。
3.交换次数
- 对于同样的数据,在排序过程中,堆排序的数据交换次数多于快速排序。而且,对于一组有序的数组来说,建堆之后反而变得无序了。
堆的应用
- 优先级队列
- 求TopK
- 求中位数