// https://en.wikipedia.org/wiki/Binary_heap // invariant: heap[parent] <= heap[child] public class BinaryHeapExtended { long[] heap; int[] pos2Id; int[] id2Pos; int size; public BinaryHeapExtended(int n) { heap = new long[n]; pos2Id = new int[n]; id2Pos = new int[n]; } public int remove() { int removedId = pos2Id[0]; heap[0] = heap[--size]; pos2Id[0] = pos2Id[size]; id2Pos[pos2Id[0]] = 0; down(0); return removedId; } public void add(int id, long value) { heap[size] = value; pos2Id[size] = id; id2Pos[id] = size; up(size++); } public void changePriority(int id, long value) { int pos = id2Pos[id]; if (heap[pos] < value) { heap[pos] = value; down(pos); } else if (heap[pos] > value) { heap[pos] = value; up(pos); } } public void remove(int id) { int pos = id2Pos[id]; pos2Id[pos] = pos2Id[--size]; id2Pos[pos2Id[pos]] = pos; changePriority(pos2Id[pos], heap[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) { long tt = heap[i]; heap[i] = heap[j]; heap[j] = tt; int t = pos2Id[i]; pos2Id[i] = pos2Id[j]; pos2Id[j] = t; id2Pos[pos2Id[i]] = i; id2Pos[pos2Id[j]] = j; } // Usage example public static void main(String[] args) { BinaryHeapExtended heap = new BinaryHeapExtended(10); heap.add(0, 4); heap.add(1, 5); heap.add(2, 2); heap.changePriority(1, 3); heap.changePriority(2, 6); heap.remove(0); // print elements in sorted order while (heap.size != 0) { System.out.println(heap.heap[0] + " " + heap.remove()); } } }