import java.util.*; // https://en.wikipedia.org/wiki/Binary_heap // invariant: heap[parent] <= heap[child] public class BinaryHeap { int[] heap; int size; public BinaryHeap(int n) { heap = new int[n]; } // build heap in O(n) public BinaryHeap(int[] values) { heap = values.clone(); size = values.length; for (int pos = size / 2 - 1; pos >= 0; pos--) down(pos); } public int removeMin() { int removed = heap[0]; heap[0] = heap[--size]; down(0); return removed; } public void add(int value) { heap[size] = value; up(size++); } void up(int pos) { while (pos > 0) { int parent = (pos - 1) / 2; if (heap[pos] >= heap[parent]) break; swap(pos, parent); pos = parent; } } void down(int pos) { while (true) { int child = 2 * pos + 1; if (child >= size) break; if (child + 1 < size && heap[child + 1] < heap[child]) ++child; if (heap[pos] <= heap[child]) break; swap(pos, child); pos = child; } } void swap(int i, int j) { int t = heap[i]; heap[i] = heap[j]; heap[j] = t; } // random test public static void main(String[] args) { Random rnd = new Random(1); for (int step = 0; step < 1000; step++) { int n = rnd.nextInt(100) + 1; PriorityQueue q = new PriorityQueue<>(); BinaryHeap h = new BinaryHeap(n); for (int op = 0; op < 1000; op++) { if (rnd.nextBoolean() && q.size() < n) { int v = rnd.nextInt(); q.add(v); h.add(v); } else if (!q.isEmpty()) { if (q.remove() != h.removeMin()) throw new RuntimeException(); } } } } }