优先队列(堆)
一、说明
在有些情况下,当有许多任务同时出现时,需要程序堆这些任务进行调度,就像windows的进程管理系统,为进程分配时间片,就是这种情况。
操作系统调度程序必须决定在若干进程中运行哪个进程。一般一个进程只被允许运行一个固定的时间片。一般来说,短的作业要尽可能快的结束,这一点很重要,因此在已经运行的作业中这些短作业应该拥有优先权。此外,有些作业虽然不短但很重要,也应该拥有优先权。
这种特殊的应用似乎需要一类特殊的队列,我们称之为优先队列(priority queue)。
二、模型
优先队列的模型基础:
- 入队(插入)
- 出队(删除最小值)
graph LR
A-->|插入|B[优先队列]
B-->|删除最小元素|C
除了操作系统外,优先队列还有很多应用,例如贪婪算法。
三、 简单实现
1、链表
-
以简单链表实现在表头插入\(O(1)\),并实现遍历删除最小\(O(N)\)。
-
维护一个有序链表,插入\(O(N)\),删除\(O(1)\)
基于删除次数肯定小于删除操作,所以方法1在一定存在上是优于方法2的。
2、二叉查找树
二叉查找树的插入和删除操作平均时间是\(O(logN)\),但是由于每次删除其实都是删除最小元素。根据查找树的性质,每次删除的都是左子树,这样对树的结构会造成比较大的影响。因为查找树的结构不只是为了插入和删除,他的结构还为了适应其他操作。所以使用查找树有些过分了!不过我们可以对二叉查找树做一些结构上的调整!让它更适合插入和删除操作。例如二叉堆。
二叉查找树:
凡你能说的,你说清楚。凡你不能说的,留给沉默!