优先级队列 是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。
优先队列是0个或多个元素的集合,每个元素都有一个优先权或值,对优先队列执行的操作有:
Create ( ):创建一个空的优先队列 Size ( ):返回队列中的元素数目 Max ( ):返回具有最大优先权的元素 I n s e rt (x):将x插入队列
DeleteMax (x):从队列中删除具有最大优先权的元素,并将该元素返回至x。
优先级队列的几种实现方式:
1)数组:
有序的时候: insert() 为 O(n) ,因为要向后移动, Max() 为O(1),
无序的时候: insert() 为O(1),Max() 为 O(n) ,因为要比较n次。
综合n的数的队列时,插入需要O(n^2)
2) 链表:大概分析同数组一样。
3)堆——此方法为最好的情况。
insert() 为O(log n),Max() 为 O(1) ,但是DeleteMax() 为O(log n), 即调整堆的时间,所以对于元素个数为n的队列,insert() 为O(n *log n ).
堆插入元素t,另x[n]=t,n=n+1,shiftup(n)
堆删除堆顶元素, 先记录x[0],然后另 x[1]=x[n], n=n-1, siftdown(n).
堆使用的数组x[0...n]需要n+1个字的额外内存。
由此得到堆排序的算法:
for( i=2; i<=n; i++)
siftup( i);// siftup(n),从i =n 开始进行调整,i=i/2
for(i=n; i>=2; i--)
{
printf( x[1]);
swap(1,i);
siftdown(i-1);//从i=1 开始调整, i=2i 或者 i=2i+1. 括号里面的参数表述堆元素的个数,并不代表开始调整的堆元素的位置。
}
// 自己很容易搞混的地方,shiftup 总是从最后一个元素开始的,shitfdown 总是从第一个元素开始的,括号里始终表示堆里剩余元素的个数。
优先队列插入和删除元素的复杂度都是O(lgn),所以很快。
另一种描述方法是采用有序线性表,当元素按递增次序排列,使用链表时则按递减次序排列,这两种描述方法的删除时间均为( 1 ),插入操作所需时间为(n).