堆是一个完全二叉树,有两种类型
- 大顶堆
- 小顶堆
父节点比他子树的节点都大
父节点比他子树的节点都小
堆的实现会经常使用数组(slice)来实现,因为完全二叉树非常适合用数组来存储;他的下标计算规则如下:
如果节点是:i;则左子树节点是:i/2+1;右子树节点是:i/2+2;父节点是:(i-1)/2
- 构建堆
- 插入元素
- 弹出堆顶元素
这就引出两种构建堆的方法(以大顶堆为例),将构建堆与弹出放在一起说,
堆构建的时候是从树的倒数第二层开始构建(因为叶子节点不需要比较),检查如果发现子节点大于它,就进行位置交换,然后对于交换后的位置继续进行检查;如果对于交换后的位置进行检查时,发现已经是叶子节点就终止;
弹出元素的第一步操作是先把堆顶元素取出,然后把最后一个元素放到堆顶;再进行一次堆构建过程,但是由于此时只需要把堆顶设置成最大即可,也采用从上往下的方式。
堆构建与弹出可以叫做:从上往下构建;
对于插入元素,首先将他放在尾部,然后从下往上的检查是否比父节点大,大就进行交换。
- 经典的
TOP N
问题,分为动态数据与静态数据 - 优先级队列,定时任务就是一个典型的应用场景
- 大顶堆与小顶堆结合求某个百分位的数字;如:中位数(50%)
- 大文件排序,但是内存有限制