码迷,mamicode.com
首页 > 编程语言 > 详细

算法—优先队列

时间:2015-11-22 15:48:20      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:

许多应用程序都需要处理有序的元素,但不一定要求它们全部有序,或是不一定要一次就将它们排序。很多情况下我们会收集一些元素,处理当前键值最大的元素,然后再收集更多的元素,再处理当前键值最大的元素,如此这般。

在这种情况下,一个合适的数据结构应该支持两种操作:删除最大元素和插入元素。这种数据类型叫做优先队列。优先队列的使用和队列(删除最老的元素)以及栈(删除最新的元素)类似,但高效地实现它则更有挑战性。

通过插入一列元素然后一个个地删掉其中最小的元素,我们可以用优先队列实现排序算法。一种名为堆排序的重要排序算法也来自于基于堆的优先队列的实现。

API

优先队列最重要的操作就是删除最大元素和插入元素,

技术分享

技术分享

优先队列的调用示例

为了展示优先队列的抽象模型的价值,考虑以下问题:输入N个字符串,每个字符串都对映着一个整数,你的任务就是从中找出最大的(或是最小的)M个整数(以及关联的字符串)。这些输入可能是金融事务,你需要从中找出最大的那些;或是农产品中的杀虫剂含量,这时你需要从中找出最小的那些;在某些应用场景中,输入量可能非常巨大,甚至可以认为输入是无限的。解决这个问题的一种方法是将输入排序然后从中找出M个最大的元素,但我们已经说明输入将会非常庞大。另一种方法是将每个新的输入和已知的M个最大元素比较,但除非M较小,否则这种比较的代价会非常高昂。只要我们能够高效地实现insert()和delMin(),下面的优先队列用例中调用了MinPQ的TopM就能使用优先队列解决这个问题。在现代基础性计算环境中超大的输入N非常常见,这些实现使我们能够解决以前缺乏足够资源去解决的问题。如表所示

技术分享

算法:

/**
 * 一个优先队列的用例
 */
public class TopM {

	//打印输入流中最大的M行
	public static void main(String[] args) {
		int M = Integer.parseInt(args[0]);
		MinPQ<Transaction> pq = new MinPQ<Transaction>(M+1);
		//为下一行输入创建一个元素并放入优先队列中
		while(StdIn.hasNextLine()){
			pq.insert(new Transaction(StdIn.readLine()));
			if(pq.size() > M){
				pq.delMin();//如果优先队列中存在M+1个元素则删除其中最小的元素
			}	//最大的M个元素都在优先队列中

			Stack<Transaction> stack = new Stack<Transaction>();
			while(!pq.isEmpty()){
				stack.push(pq.delMin());
			}
			for (Transaction t : stack) {
				StdOut.println(t);
			}
		}
	}
}

这段代码调用了MinPQ并会打印数字最大的M行。

技术分享

 

源码下载

算法—优先队列

标签:

原文地址:http://www.cnblogs.com/joey-hua/p/4985898.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!