优先级队列:按照事先约定的优先级,可以始终高效查找并访问优先级最高数据项的数据结构。
可以将堆继承于向量的数据结构,优先级队列ADT的size(),insert(),getMax(),delMax()四个接口。
堆的成员:词条也是向量的元素,有大小N确定。
应用接口:可反复使用delMax接口实现排序算法。
如何确保insert(),getMax(),delMax()的时间复杂度均可达到o(logn);
无论是向量还是列表均无法实现该要求,无需保证全体词条之间的全序关系。
有限偏序集的极值必然存在,故因此借助堆结构来实现,也就是树结构特例。
完全二叉堆的其中一种:完全二叉树,条件二:根节点均不大于或不小于子节点。
大顶堆:优先级最高的词条在堆顶为大顶堆。优先级最低的词条在堆顶,为小顶堆。
基于向量结构实现堆结构。完全二叉树可用向量实现。节点之间的关系由位置RANK确定。
1.词条插入堆中:将词条添加到向量末尾,再对堆执行上滤操作。
2.获取优先级最高或最低的词条:返回向量的首单元。
3.删除优先级最高的的词条:堆顶词条=末尾词条,舍弃末尾词条,对新堆顶实现下滤。
堆的上滤操作:判断该元素是否有父亲;
若有,看是否逆序,若逆序,则调换
直到不再逆序或达到堆顶。
由于完全二叉堆中元素均按照层次遍历存储在向量结构中,所以各节点在物理上连续,可利用RANK判断父子关系。
只要i>0,则有父节点=i/2-1;
i*2+1满足[0,N)之间,则合法,且左孩子为i*2+1
i*2+2满足[0,N)之间,则合法,且右孩子为i*2+2
堆的下滤操作: 判断i是否有两个孩子,有,则与最大的那个交换,
若只有一个左孩子,则与左孩子看最大的那个交换。
建堆:给定一组词条,如何高效地将他们建成堆。
方法一:insert()插入法,O(NLOGN);
方法二:将所有词条插入向量中,自顶向下对每个词条进行上滤操作。O(LOGN).深度
方法三:Floyd算法,自下而上,依次对每一个内部节点进行下滤。O(N)。高度
方法三优于方法二的原因是:在完全二叉树树中,深度小的点,远远少于高度小的节点。
堆排序:反复调用delmax()方法,实际运行时间往往高于O(nlogn)时间。
也就证明堆结构优于向量结构。
左式堆:除了标准的插入和删除操作,堆结构的另一个常见操纵为合并。由列表构成。
方法一:反复取出堆的最大词条并插入另外一个堆中。