优先队列----堆

来源:互联网 发布:视频剪辑配乐软件 fcp 编辑:程序博客网 时间:2024/05/21 10:07

问题

打印机打印作业一般是放在队列中的。如果按照先来先打印的顺序,有一个100页的打印任务,那么会让后面短小的任务等待很长时间。更合理的做法也许是最后处理最耗时的打印任务,不管它是不是最后提交上来的。
在多用户操作系统中,操作系统让哪个程序使用CPU,是需要决定从队列里面选择的。一般做法是从队头获得程序,分配一定时间的时间片。如果执行完,从队列删除;如果没有执行完,插入队尾。这样处理的缺点是:一些很短小的程序需要花很长的时间才能执行完;有些比较重要的程序,不一定短小需要提前执行。
因此如果队列中的每个任务都有一个优先级,先执行优先级高的,就可以解决问题了。这样的队列称为优先队列(priority queue)。

优先队列定义

优先队列是要很小的代价完成插入和删除最小元素,两个操作的数据结构。

二叉堆

通常情况下的堆是指二叉堆。思路是每次插入都将最小元素(如果业务要求是找最小元素),放置在根节点,用O(logN)时间完成。可以用O(1)的时间获得最小元素。删除最小元素的时候除了返回最小元素的值,还将选取新的最小元素,用O(logN)的时间。

结构性质

二叉堆是一棵被完全填满的二叉树,有可能最底层元素不满,底层上的元素从左到右。(关键词:满二叉树、从左到右)

堆序性质

对最小堆而言:每一个节点X>父节点的值。最大堆相反。

操作

操作的时间复杂度小于O(logN)

insert

deleteMin

decreaseKey

increaseKey

delete

buildHeap

优先队列应用

选择问题

输入N个元素,查找第k小元素。解决思路1:将N个元素build一棵最小二叉堆,删除k次,得到第k小元素。解决思路2:前k个元素build一棵最大二叉堆,后面的每个元素读入的时候,与这里的最大元素比较,如果比最大元素小,则替换。

事件模拟

d堆

堆的分叉是d个,不仅仅是2个。有效降低堆的高度。实际中多用4-堆。

左势堆

二叉堆不能很方便的合并,所以提出了左式堆。左式堆是一个二叉堆。不同点是堆中每隔一节点X,左儿子的零路径长>=右儿子的零路径长,记为:nlp(left)>=nlp(right)。整棵树向左偏。

特殊操作

merge

时间复杂度 O(logN)

斜堆

二项队列

每次操作的最坏情形是O(logN),而插入操作平均花费常数时间。
一个二项队列是堆序的树的集合(简单的说就是树的集合)。二项队列中每一个高度的树只有一颗
这里写图片描述

这里有B0,B1,B2,B3,B4Bk=Bk1Bk1
高度为k的二项树恰好有2k个节点。我们就可以用二项队列表示任意一个优先队列。这与二进制表示一个数相同。例如6,的二进制是1101,B0,B2,B3三棵树可以表示容量为6的优先队列。

代码任务

1 二叉堆的实现
2 左势堆的合并
3 二项队列的实现

0 0
原创粉丝点击