数据结构与算法分析之优先队列(堆)



1.优先队列,也叫二叉堆,简称堆。


2.同二叉查找树一样,堆也有两个性质,即结构性和堆序性。


3.堆的结构性质
堆是一棵被完全填满的二叉树,有可能的例外在底层,底层上的元素从左到右填入。
这样的树称为完全二叉树(complete binary tree)。

4.一棵高度为h的完全二叉树有2^h到2^(h+1) - 1个节点


5.由于完全二叉树的规律性,它可以用一个数组来实现而不需要指针。
排除数组中位置0,在数组中任一位置i上的元素,其左儿子在位置2i上,
右儿子在左儿子后的单元(2i+1)上。它的父亲节点在位置i/2上。
数组实现方法的唯一问题在于,要事先估计堆的大小。


6.堆的堆序性质
能使操作被快速执行的性质是堆序性。在一个堆中,对于每一个节点X,X的父亲中的关键字小于X中的关键字,根节点除外。
所以最小值在根节点上,因此FindMin会以常数时间完成运算。这种结构像是从大到小向上堆起来的一个堆。

7.堆的基本操作操作
a.Insert插入操作
为了在插入过程中保证堆的序,一般使用的策略是上滤。
插入过程是:在堆的下一个空闲位置创建一个空穴,若X放在该空穴中并且不破坏堆的序则插入完成;
否则将空穴的父亲节点元素移入该空穴,这样空穴就会朝着根的方向上滤。循环上面的过程,直到X
能被放入空穴为止。

b.DeleteMin(删除最小元)
最小的元在根节点处,为了保持堆的结构性质和堆序性质,删除时和插入的策略是类似的,即下滤。
删除操作会导致堆的最后一个元素X移动到合适的位置,先将删除的地方视作一个空穴,
并将空穴的儿子节点中较小的那个替换空穴,重复此过程直到X能放入到某个空穴为止。

以下3种方法必须通过某种方法得知每个元素的位置,才能以对数最坏情形执行。
c.DecreaseKey(降低关键字的值)
DecreaseKey(P, delta, H)操作会降低在位置P处的关键字的值,降值得幅度为delta。这种操作用于系统管理程序,
系统管理程序能够使它们的程序以最高优先级来运行。

d.IncreaseKey(增加关键字的值)
IncreaseKey(P, delta, H)操作将增加在位置P处的关键字的值,增值幅度为delta。可以用下滤来完成。

e.Delete(删除)
Delete(P, H)操作将删除堆中位置P上的节点。先执行DecreaseKey(P,无穷大,H),然后再执行DeleteMin(H)。
主要用于当一个进程被用户终止时,它必须从优先队列中删除。

f.BuildHeap(构建堆)

8.按照最小元设计的堆(也称作最小值堆)在求最大元方面却无任何帮助。实际上一个堆所蕴含的序的信息很少,
我们只能确定最大元在树叶节点上。

9.优先队列的应用
a.选择问题
即在一组数中查找第k个最小或者最大的元素。先使用BuildHeap构建一个堆,然后执行k次DeleteMin,
得以找到第k个最小元。构建堆的最坏情形用时是O(N),执行k次DeleteMin的总运行时间是O(N + klogN),
总的运行时间是ceita(N log N)。可以对此进一步细化得到堆排序的应用算法。


b.事件模拟
即对系统调度问题的模拟


10.堆的缺点
除了不能执行精确Find外,堆的另一个明显缺点是将两个堆进行合并是困难的。

11.d-堆
d-堆是对二叉堆的简单推广,只是所有的节点都有d个儿子(因此,二叉堆是2-堆)。

12.左式堆
a.任意节点X的零路径长(null path length, NPL)Npl(X)定义为从X到一个没有两个儿子节点的最短路径的长。
所以,具有0个或1个儿子的节点的Npl为0,Npl(NULL) = -1
任一节点的零路径长比它的诸儿子节点的零路径长的最小值多1.
b.左式堆性质:对于堆中的每一个节点X,左儿子的零路径长要大于或等于与右儿子的零路径长。
c.左式堆的性质使得树向左增加深度,因此得名左式堆。这样做是为了方便合并操作。
因为左式堆趋于加深左路径,所以堆中右路径最短。
d.左式堆相关的定理:在右路径上有r个节点的左式树必然至少有2^r - 1个节。从这个定理可以得到,N个节点
的左式树有一条右路经最多含有log(N + 1)个节点
e.对左式堆操作的一般思路是将所有的工作放到右路径上进行。

13.左式堆的操作
左式堆的基本操作是合并,插入只是合并的特殊情形。根据左式堆的操作要集中在右子堆上这一性质,
合并的基本过程是,先将具有较小根值的堆H1的右子堆和具有较大根值的堆H2合并,合并后有可能会在较小根值
的根H1处破坏Npl性质,恢复Npl性的方法很简单即将H1的左右子树互换,最后一步是更新新根H1的Npl= H1->Right->Npl + 1.
递归执行上面的过程得以完成合并操作。
其他的操作如Insert和DeleteMin操作都可以看作是合并操作的变种。

合并操作的时间界是O(log N),同理DeleteMin操作的时间界也是O(log N)

14.斜堆(skew heap)
a.斜堆和左式堆间的关系类似于伸展树和AVL树之间的关系。斜堆是具有堆序的二叉树,但是不存在对树的结构限制。
b.与左式堆相同,斜堆的基本操作也是合并操作。


15.二项队列
二项队列不是一棵堆序树,而是堆序树的集合,称为森林。堆序树中每一颗都是有约束的形式,叫做二项树。
高度为0的二项树是一棵单节点树;高度为k的二项树Bk通过将一颗二项树B(k-1)附接到另一颗二项树B(k-1)的根上构成。
综上,二项树Bk由一个带有儿子B0,B1,...,B(k-1)的根组成。高度为k的二项树恰好有2^k个节点,而在深度d处的节点数是二项系数(k  d)

a.合并两棵二项树要花费常数时间,二项队列中总共存在O(log N)棵二项树,因此合并在最坏的情形下花费时间O(logN)。
b.二项队列的插入操作最坏时间界为常数O(N),即初始队列为空时。
c.二项队列的实现:
由于DeleteMin操作需要快速找出根的所有子树的能力,因此,需要一般树的标准表示方法:
即每个节点的儿子都存在一个链表中,而且每个节点都有一个执行它第一个儿子节点的指针。
该操作还要求诸儿子按照它们的子树的大小排序(递减的顺序)。

你可能感兴趣的:(数据结构与算法分析)