优先级队列+堆

来源:互联网 发布:姓名学五格三才计算法 编辑:程序博客网 时间:2024/05/16 10:53

优先级队列 是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。

优先队列是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).
  DeleteMax (x):从队列中删除具有最大优先权的元素,并将该元素返回至x
  }
  优先队列插入和删除元素的复杂度都是O(lgn),所以很快。e ( ):创建一个空的优先队列
  Size ( ):返回队列中的元素数目
  Max ( ):返回具有最大优先权的元素
  I n s e rt (x):将x插入队列
  DeleteMax (x):从队列中删除具有最大优先权的元素,并将该元素返回至x
  }
  优先队列插入和删除元素的复杂度都是O(lgn),所以很快。