iltonmi's docs

二叉堆和优先级队列

参考资料:Algorithms, 4th

精髓

In a heap, the parent of the node in position k is in position ⎣k /2⎦ and, conversely, the two children of the node in position k are in positions 2k and 2k + 1.

这句话就是优先级队列的精髓:

​ 在堆中,节点k的2个孩子节点在位置2k和2k+1,相反的,节点k的父节点在位置floor(k/2)。

固定大小的优先级队列的代码实现(不需要resize)

public class MaxPQ<Key extends Comparable<Key>> 
{
     private Key[] pq; // heap-ordered complete binary tree
     private int N = 0; // in pq[1..N] with pq[0] unused
    
     public MaxPQ(int maxN)
     { pq = (Key[]) new Comparable[maxN+1]; }
    
     public boolean isEmpty()
     { return N == 0; }
    
     public int size()
     { return N; }
    
     public void insert(Key v)
     { 
         pq[++N] = v;
         swim(N);
     }
     public Key delMax()
     { 
         Key max = pq[1]; // Retrieve max key from top.
         exch(1, N--); // Exchange with last item.
         pq[N+1] = null; // Avoid loitering.
         sink(1); // Restore heap property.
         return max;
     }
     
    //上浮
    private void swim(int k) {
        while(k > 1 && less(k / 2, k)) {
            exch(k / 2, k);
            k /= 2;
        }
    }
    
    //下沉
     private void sink(int k) {
         while(2 * k <= N) {
            int j = 2 * k;
             if(j < N && less(j, j + 1)) {
                 j++;
             }
             if(!less(k, j)) {
                 break;
             }
             exch(k, j);
             k = j;
         }
     }
    
     private boolean less(int i, int j) {
         return pq[i].compareTo(pq[j]) < 0;
     }
    
     private void exch(int i, int j) {
         Key t = pq[i];
         pa[i] = pq[j];
         pq[j] = t;
     }
    
}

Comparator实现:

class MinPQ<E> {

    private Object[] q;
    private Comparator<? super E> cmp;
    private int size;

    public MinPQ(int maxSize, Comparator<? super E> cmp) {
        q = new Object[maxSize+2];
        this.cmp = cmp;
    }

    public void insert(E e) {
        q[++size] = e;
        swim(size);
    }

    public E delMin() {
        Object minVal = q[1];
        swap(1, size);
        q[size] = null;
        size--;
        sink(1);
        return (E) minVal;
    }

    public E peek() {
        return (E)q[1];
    }

    private void swim(int k) {
        while(k > 1 && larger(k / 2, k)) {
            swap(k / 2, k);
            k /= 2;
        }
    }

    private void sink(int k) {
        while(2 * k <= size) {
            int j = 2 * k;
            if(j < size && larger(j, j + 1)) {
                j++;
            }
            if(!larger(k, j)) {
                break;
            }
            swap(k, j);
            k = j;
        }
    }

    private boolean larger(int i, int j) {
        return cmp.compare((E) q[i], (E) q[j]) > 0;
    }

    private void swap(int i, int j) {
        Object temp = q[i];
        q[i] = q[j];
        q[j] = temp;
    }

    private int size() {
        return this.size;
    }
}

posted on 2021-01-26 00:41  iltonmi  阅读(33)  评论(0编辑  收藏  举报

导航