java 优先队列(基于最大堆)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 优先队列(基于最大堆)相关的知识,希望对你有一定的参考价值。

public class MaxPQ<Key extends Comparable<Key>> {
    private Key[] pq;   // 数据存储与pq[1...N]中
    private int N = 0;

    public MaxPQ(int maxN) {
        pq = (Key[]) new Comparable[maxN + 1];
    }

    public boolean isEmpty() {
        return N == 0;
    }

    public int size() {
        return N;
    }

    /**
     * @description N加一并把新元素添加在数组最后,然后用swim()恢复堆的秩序
     * @param v
     */
    public void insert(Key v) {
        pq[++N] = v;
        swim(N);
    }

    /**
     * @description 从pq[1]得到需要返回的元素,将pq[N]移动到pq[1],N减一并用sink()恢复堆的秩序
     * @return
     */
    public Key delMax() {
        Key max = pq[1];
        exch(1, N--);
        pq[N + 1] = null;
        sink(1);
        return max;
    }

    private boolean less(int i, int j) {
        return pq[i].compareTo(pq[j]) < 0;
    }

    private void exch(int i, int j) {
        Key temp = pq[i];
        pq[i] = pq[j];
        pq[j] = temp;
    }

    /**
     * @description 由下至上的堆有序化(上浮):如果某个结点大于它的父结点,就交换它和它的父结点
     *               位置为k的结点的父结点位于⌊k/2⌋
     * @param k
     */
    private void swim(int k) {
        while (k > 1 && less(k / 2, k)) {
            exch(k / 2, k);
            k = k / 2;
        }
    }

    /**
     * @description 由上至下的堆有序化(下沉):如果某个结点比它的两个子结点或是其中之一更小,就交换它和它的两个子结点中的较大者
     *               位置为k的结点的子结点位于2k和2k+1
     * @param k
     */
    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;
        }
    }
}

以上是关于java 优先队列(基于最大堆)的主要内容,如果未能解决你的问题,请参考以下文章

手动实现最小堆和最大堆(优先队列)

Black Box--[优先队列 最大堆最小堆的应用]

最大堆与堆排序和优先队列

[数据结构]优先级队列(最大堆)详解

优先级队列实现

优先队列(堆)经典例题——poj1442 black fox