学习笔记堆Heap和 二叉堆 Binary Heap

1.堆 Heap

定义:可以迅速找到一堆数中的最大值或者最小值的数据结构。
应用场景:经常是一个数一个数的过来,比如找最大值或者找最小值
分类:堆本身是一个抽象的数据结构,根据实现形式,将其分为二叉堆、斐波那契堆等。
P.S: 二叉堆是堆(优先队列 priority_queue) 的一种常见且简单的实现,但是并不是最优的实现形式,但是在面试的时候以及教科书上出现比较多。真正在工程中使用的是 严格斐波那契堆等性能优异的堆,面试的时候知道有这么一种堆就行,暂时没必要知道怎么实现的。
在这里插入图片描述
参考
将根节点最大的堆叫做大顶堆或者大根堆,根结点最小的堆叫做小顶堆或者小根堆。
假设是大顶堆,则常见操作(API):

操作 复杂度
find-max O(1)
delete-max O(logN)
insert (create) O(logN) or O(1)

2.二叉堆(Binary Heap)

二叉堆事通过完全二叉树来实现的(注意:不是二叉搜索树),如下图:
二叉堆(以大顶堆为例)。它满足下列性质:

  1. 是一颗完全二叉树
  2. 树中任意节点的值都是 >= 其子节点的值
    P.S:
    完全二叉树:在一颗二叉树中,若除最后一层外的其余层都是满的,并且最后一层要么是满的,要么在右边缺少连续若干节点,则此二叉树称为完全二叉树(Complete Binary Tree)
    参考
    在这里插入图片描述

二叉堆的实现细节

  • 二叉堆一般都是通过 数组来实现
    (P.S:注意此处不是通过链表来实现的)
  • 假设 “第一个元素” 在数组中的索引为 0 的话。则父节点和子节点的位置关系如下:
  1. 索引为 i 的左孩子的索引是( 2 * i + 1)
  2. 索引 为 i 的右孩子的索引是 (2 * i + 2)
  3. 索引为 i 的父亲节点的索引是 floor((i - 1)/2),即父亲节点为 ( i - 2) / 2 取整
    在这里插入图片描述

Insert 插入操作
6. 新元素一律先插入到堆的尾部
(如果堆是用一维数组实现的话,将新元素插入到尾部就是在数组尾部添加元素)
7. 依次向上调整整个堆的结构(一直到根即可)
HeapifyUp 向上调整
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Delete Max 删除堆顶操作

  1. 将堆尾的元素替换到顶部(即堆顶被替代删除)
  2. 依次从堆根部向下调整整个堆的结构(一直到堆尾即可)
    HeapifyDown
    在这里插入图片描述