基于堆的优先队列
1.概念:
优先队列:普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。通常采用堆数据结构来实现。(百度百科)
二叉堆:二叉堆时一组能够用堆有序的完全二叉树排序的元素,并在数组中按照层级储存。
2.堆算法:
(1)由下至上的堆有序化(上浮)
当出现某个结点比它的父节点更大,则需要通过上浮来调整堆,使堆重新有序。
方法为交换它与它的父节点,直到它小于它的父节点为止。a[k]的父节点为a[k/2]
代码:
private void swim(int k){ while(k>1&&pq[k]>pq[k/2]){ swap(pq[k],pq[k/2]); k=k/2; } }
(2)由上至下的堆有序化(下沉)
当出现某个节点比它的子节点小,则需要下沉调整堆。
方法:将此节点与它的子节点中较大的那个交换。a[k]的子节点为a[2k]和a[2k+1]
代码:
private void sink(int k){ while(2*k<=N){ int j=2*k; if(j<N&&pq[j]<pq[j+1]) j++; if(pq[k]>=pq[j]) break; swap(pq[k],pq[j]); k=j; } }
3.基于对的优先队列代码实现:
1 class MaxPQ{ 2 private int[] pq; 3 private int N=0; 4 5 public MaxPQ(int maxN) { 6 pq=new int[N+1]; 7 } 8 private void swim(int k){ 9 while(k>1&&pq[k]>pq[k/2]){ 10 swap(pq[k],pq[k/2]); 11 k=k/2; 12 } 13 } 14 private void sink(int k){ 15 while(2*k<=N){ 16 int j=2*k; 17 if(j<N&&pq[j]<pq[j+1]) 18 j++; 19 if(pq[k]>=pq[j]) 20 break; 21 swap(pq[k],pq[j]); 22 k=j; 23 } 24 } 25 public void insert(int k) { 26 pq[++N]=k; 27 swim(N); 28 } 29 public int delMax() { 30 int max=pq[1]; 31 pq[1]=pq[N]; 32 N--; 33 sink(1); 34 return max; 35 } 36 }
参考资料:《算法(第4版)》,美 Robert Sedgewick / 美Kevin Wayne,人民邮电出版社