普林斯顿公开课 算法4-1:优先级队列API和基本实现
时间:2014-06-10 08:15:43
收藏:0
阅读:379
优先级队列是容器的一种,可以向优先级队列中添加或取出数据,取出数据时只能取出最大的数或最小的数。而其他的一些容器比如队列和栈,取出的顺序跟插入的顺序是有关的。
优先级队列的接口如下:
public class MaxPQ<Key extends Comparable<Key>> { MaxPQ(); void insert(Key x); Key popMax(); boolean isEmpty(); }
优先级队列的应用
-
事件驱动的模拟
-
数字运算
-
数据压缩
-
图的查找
-
数论
-
人工智能(A*查找)
-
统计学
-
操作系统(负载平衡)
-
离散优化(背包问题)
-
垃圾邮件过滤(贝叶斯垃圾过滤)
栈和队列是优先级队列的特殊情况
问题举例
现在有一个很大的txt文件,文件中包含了许多整数,文件中的数据量非常大,无法将整个文件读取到内存中。求该文件中最大的5个整数。
解答
这个问题就要用优先级队列进行求解,每次读取一行,将数据加入到优先级队列,如果队列的长度大于5,就删除最小的元素。当整个文件读取完毕时,优先级队列中剩余的元素就是要求的最大5个数。
复杂度
设需要在N个数据中求出最大的M个元素。
-
如果用排序算法进行求解,时间复杂度是N logN,空间复杂度是N。
-
如果用基础优先级队列进行求解,时间复杂度是N logM,空间复杂度为M。
-
如果用堆的数据结构来做,那么时间复杂度是N logM,空间复杂度是M。
-
理论上能达到最小的时间复杂度是N,空间复杂度是M。
使用堆的算法来求解该问题时,它的复杂度已经非常接近理论极限了。
代码
下面展示了最简单的优先级队列实现方法。插入的复杂度是1,删除的复杂度是N。
public class UnorderedPQ<Key extends Comparable<Key>> { private Key[] items; private int N; public UnorderedPQ(int capacity) { items = (Key[])new Comparable[capacity]; } public void insert(Key item) { items[N] = item; N++; } public Key popMax() { // 找出最大的数字 int max = 0; for(int i=1;i<N;i++){ if(SortUtil.less(items[max], items[i])) { max=i; } } // 删除最大的数字 Key result = items[max]; SortUtil.exch(items, max, N-1); // 注意:这里是N-1,不是N N--; // 返回最大的数 return result; } public boolean isEmpty() { return N==0; } }
评论(0)