数据结构与算法(七)堆

优先级队列:按照事先约定的优先级,可以始终高效查找并访问优先级最高数据项的数据结构。

可以将堆继承于向量的数据结构,优先级队列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)时间。

也就证明堆结构优于向量结构。

左式堆:除了标准的插入和删除操作,堆结构的另一个常见操纵为合并。由列表构成。

方法一:反复取出堆的最大词条并插入另外一个堆中。

猜你喜欢

转载自blog.csdn.net/u013070875/article/details/85724321
今日推荐