什么是堆
堆是一种数据结构,它可以看做一棵
完全二叉树
。但是它又是被存储成数组形式的。堆又分为最大堆和最小堆。
最大堆
:一棵完全二叉树的任意一个节点都大于等于它的左右子节点(如果有的话)
最小堆
:一棵完全二叉树的任意一个节点都小于等于它的左右子节点(如果有的话)
我们以最小堆为例。
如图:
上图是一棵完全二叉树,同时也是最小堆。它的任意节点都小于等于它的子节点。如果用数组表示的话,就用层次遍历的方式,表示为[5, 9, 11, 14, 18, 19, 21, 33, 17, 27]。
因为是一棵完全二叉树,所以堆有一些特性。
1.最小(大)堆的根节点(第一个元素)是整棵数最小(大)的。
2.除根节点外,节点k的父节点索引是k/2,左右子节点(如果有的话)为2k和2k+1。注:索引从1开始,而非0
所以堆也是一种
优先队列
,我理解的优先队列,就是它不是一个完全有序的队列,但是又有一定的顺序,例如最大(小)能一下找到。所以是一种有着优先级别的队列。
堆的实现(以最小堆为例,最大堆同理):
1.插入(insert)
插入的过程是,先将新的节点放在最末尾,然后依次与它的父节点比较,如果比父节点小,那么就交换位置。一直到比它的父节点大为止。这个过程称为
上浮
。
上图的过程:
1.原数组为[5, 9, 11, 14, 18, 19, 21, 33, 17, 27],插入新的元素[5, 9, 11, 14, 18, 19, 21, 33, 17, 27,
7
]
2.比较7和它的父节点18, 7<18,交换它们的位置。[5, 9, 11, 14,
7
, 19, 21, 33, 17, 27,
18
]
3.再比较7和它的父节点9. 7<9,交换。[5,
7
, 11, 14,
9
, 19, 21, 33, 17, 27,18]
4.再比较7和它的父节点5. 7>5, 停止交换,7已经到了正确的位置。所以最终的树为[5, 7, 11, 14, 9, 19, 21, 33, 17, 27,18]
用代码实现:
class BinHeap:
def __init__(self):
self.heapList = [