/** * Priority Queue API * Generic items are comparable * <p> * MaxPQ(): create an empty priority queue * MaxPQ(Key[] a): create a priority queue with given keys * void insert(Key v): insert a key into the priority queue * Key delMax(): return and remove the largest key * boolean isEmpty(): is the priority queue empty? * Key max(): return the largest key * int size(): number of entries in the priority queue * <p> * binary heap-ordered array: start from 1, if children is k, parent is k / 2 * if parent is k, children are 2k and 2k + 1 * * @author kiyan * @since 5/25/16. */ public class MaxPQ<Key extends Comparable<Key>> { private Key[] pq; private int N; /** * add no-arg constructor and use resizing array */ public MaxPQ(int capacity) { pq = (Key[]) new Comparable[capacity + 1]; } public MaxPQ(Key[] a) { } public void insert(Key v) { pq[++N] = v; swim(N); } /** * should throw exception when empty */ public Key delMax() { Key max = pq[1]; exch(1, N--); sink(1); pq[N + 1] = null; // prevent loitering return max; } public boolean isEmpty() { return N == 0; } public Key max() { return pq[1]; } public int size() { return N; } /** * heap promotion: when child's key becomes larger than it's parent * solution: exchange key in child with key in parent, repeat util heap order restored */ private void swim(int k) { while (k > 1 && less(k / 2, k)) { exch(k / 2, k); k = k / 2; } } private void exch(int i, int k) { Key temp = pq[i]; pq[i] = pq[k]; pq[k] = temp; } private boolean less(int i, int k) { return pq[i].compareTo(pq[k]) < 0; } private boolean greater(int i, int k) { return pq[i].compareTo(pq[k]) > 0; } 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; } } }