/** A min-heap. */ class Heap<E extends Comparable<E>> { //traditionally use E[] and size variable, but... private ArrayList<E> array = new ArrayList<E>(); /** Constructs an empty heap. */ public Heap() { } public void add(E item) { array.add(item); //add to end heapifyUp(array); } /** * Adjusts position of last element as necessary. * Assumes the rest of the array is already a valid heap. */ private void heapifyUp(ArrayList<E> array) { int i = array.size() - 1; //last element int parent = (i - 1) / 2; while (i > 0 && array.get(i).compareTo(array.get(parent)) < 0) { //item is smaller than parent so needs to move up Collections.swap(array, i, parent); i = parent; parent = (i - 1) / 2; } } }
public E remove() { if (array.size() == 0) { throw new IllegalStateException("Heap is empty."); } E root = array.get(0); array.set(0, array.remove(array.size() - 1)); heapifyDown(array); return root; } /** * Adjust position of first element as necessary. * Assumes that the rest of array is already heapified. * That is, elements at index 1 and 2 are roots of valid heaps. */ private void heapifyDown(ArrayList<E> array) { int i = 0; while (i < array.size()) { //or while(true) int indexOfMin = i; int left = 2 * i + 1; int right = 2 * i + 2; if (left < array.size() && array.get(left).compareTo(array.get(indexOfMin)) < 0) { indexOfMin = left; } if (right < array.size() && array.get(right).compareTo(array.get(indexOfMin)) < 0) { indexOfMin = right; } if (i == indexOfMin) { break; }else { Collections.swap(array, i, indexOfMin); i = indexOfMin; } } }
For more complex heap implementations:
Remember:
public static <E extends Comparable<E>> void heapSort(E[] array) { //heapify from bottom up, skipping all leaves, which are already heaps of size 1 for (int i = array.length / 2; i >= 0; i--) { heapify(array, i, array.length); } // grab max element from heap and swap to end of array for (int i = array.length - 1; i > 0; i--) { //swap root to end of array E temp = array[0]; array[0] = array[i]; array[i] = temp; heapify(array, 0, i); } } /** * Produces a max-heap rooted at the given root index and containing a number * total elements equal to length. Assumes that the children at * (2 * root + 1) and (2 * root + 2) are the roots of valid heaps. */ private static <E extends Comparable<E>> void heapify(E[] array, int root, int length) { //basically heapifyDown method for an array int i = root; while (true) { int indexOfMax = i; int left = 2 * i + 1; int right = 2 * i + 2; if (left < length && array[left].compareTo(array[indexOfMax]) > 0) { indexOfMax = left; } if (right < length && array[right].compareTo(array[indexOfMax]) > 0) { indexOfMax = right; } if (i == indexOfMax) { break; }else { //swap E temp = array[i]; array[i] = array[indexOfMax]; array[indexOfMax] = temp; i = indexOfMax; } } }
Given an int array A and an int value X, print all index pairs (i,j) such that A[i] + A[j] == X.
Is your solution optimal (ie, most efficient in terms of worst-case big-O)? Prove it.