一、定义
在优先队列中,元素被赋予优先级。当访问优先队列的元素时,具有最高优先级的元素最先被访问。此种数据结构支持两种操作:删除最大元素和插入元素。
二、为什么要使用优先队列这种数据结构?
若总数据量太大,无法排序。需求是你需要从10亿格尔元素中选择最大的十个,排序是不现实的。但是有了优先队列,那我们只需要用一个能存储十个元素的队列即可。每次比较之后都是删除较小的元素,使得队列中的元素始终保持最大。
例如:输入N个字符串,每个字符串都对应一个整数,我们需要找出最大的M个整数(算法第四版代码,需要下载本书自带的jre才能运行)。
public class TopM{
public static void main(String []args){
int M=Integer.parseInt(args[0]);
//创建一个初始容量为M+1的优先队列
MinPQ<Transaction> pq=new MinPQ<>(M+1);
while(StdIn.hasNextLine()){
pq.insert(new Transaction(StdIn.readLine()));
if(pq.size>M)
pq.delMin();
}
Stack<Transaction> stack=new Stack<>();
while(!pq.isEmpty())
stack.push(pq.delMin());
for(Transaction t:stack)
System.out.println(t);
}
}
三、优先队列的初级实现
1.数组实现(无序)
//优先队列的数组的无序实现(只实现主要的代码)
class Unorder{
private int []a;
private int count=0;
public Unorder(int max){
a= new int[max];
}
private int size(){
return count;
}
void insert( int v){
if(this.count+1>=a.length)
delMin();
else
a[count++]=v;
}
int delMin(){
int min=0;
for(int j=1;j<a.length;j++)
if(a[j]<a[min])
min=j;//min是最小元素的下标
//移动元素
for(int i=min;i<a.length-1;i++)
a[i]=a[i+1];
count--;
return a[min];
}
}
2.数组实现(有序)---》只需每次更新最小的元素即可,直接替换,故在此不重复实现
3.使用链表表示法(同样是两种,有序链表和无序链表)(附上链式队列的程序,添加删除最小的元素即可)
public class LinkedQueue<Item> {
private int N=0;
private class Node{
Item item;
Node next;
}
private Node first=null,last=null;
public boolean isEmpty(){
return N==0;
}
public int size(){
return N;
}
public void enQueue(Item item){
Node oldlast=last;
last=new Node();
last.item=item;
last.next=null;
if(isEmpty())
first=last;
else
oldlast.next=last;
N++;
}
public Item deQueue(){
Item item=first.item;
first=first.next;//Java 垃圾自动回收机制
if(isEmpty())
last=null;
N--;
return item;
}
4.个人在实现的时候建议采用使用有序序列(解决问题的积极方法),这样可以使得后序的操作变得更加高效。避免使用惰性方法,不要在必要的时候才采取行动,要未雨绸缪。