基于堆的优先队列

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,人民邮电出版社

 

posted @ 2019-10-30 20:55  teensSpirit  阅读(215)  评论(0编辑  收藏  举报