1、heap的概述
heap(堆)并不归属于 STL 容器组件,它是个幕后英雄,扮演 priority queue(优先队列)的助手。priority queue 允许用户以任何次序将任何元素推入容器,但取出时一定是从优先权最高的元素开始取。而 binary max heap(最大二叉堆)具有这样的特性,适合作为 priority queue 的底层机制。 因为后面要整理 priority queue,所以要先把 heap整理好。
虽然 binary search tree(二叉搜索树)也可以作为 priority queue 的底层。但杀鸡用牛刀,一来 binary search tree 的输入需要足够的随机性,二来 binary search tree 并不容易实现。 priority queue 的复杂度,最好介于 queue 和 binary search tree 之间,才适得其所。
所谓的 binary heap (二叉堆)就是一种 complete binary tree(完全二叉树),整棵 binary tree 除了最底层的叶节点之外是填满的,而最底层的叶节点由左至右又不得有空隙。如下图所示:
complete binary tree 整棵树没有任何节点漏洞,这带来一个极大的好处:我们可以利用array来存储所有节点。将 array 的 #0 元素保留(或设为无限大或无限小值),那么当 complete binary tree 中的某个节点位于 array 的 i 处时,其左子节点必位于array的 2i 处,其右子节点必位于 array 的 2i+1 处,其父节点必位于 “i/2” 处。通过这么简单的位置规则,array 可以轻易实现出 complete binary tree 。这种 array 表述 tree 的方式,我们称为隐式表述法。
这样一来,我们需要的工具就很简单了:一个array和一组heap算法(用来插入元素、删除元素、取极值,将某一整组数据排列成一个heap)。array 的缺点是无法动态改变