@Nullable private T getParent(int position) { final int index = getParentIndex(position); if (isValidIndex(index)) { return get(index); } else { return null; } }
@Nonnull public T getRoot() { return get(getRootIndex()); }
@Nullable private T getOrNull(int index) { final T value; if (isValidIndex(index)) { value = get(index); } else { value = null; } return value; }
public static <T> void heapSort(@Nonnull T[] a, @Nonnull Comparator<? super T> c) { final ArrayBinaryHeap<? super T> heap = heapify(a, c); final int rootIndex = heap.getRootIndex(); for (int i = a.length - 1; i >= 1; i--) { swap(a, i, rootIndex); heap.decreaseSize(); heap.bubbleDown(rootIndex); } } }
void bubbleDown(int currentIndex) { final T current = getOrNull(currentIndex); if (current != null) { final int leftIndex = getLeftChildIndex(currentIndex); final T left = getOrNull(leftIndex); final int rightIndex = getRightChildIndex(currentIndex); final T right = getOrNull(rightIndex); int largestIndex = currentIndex; T largest = current; if (left != null && comparator.compare(left, current) > 0) { largestIndex = leftIndex; largest = left; } if (right != null && comparator.compare(right, largest) > 0) { largestIndex = rightIndex; largest = right; } if (largestIndex != currentIndex) { swap(array, largestIndex, currentIndex); bubbleDown(largestIndex); } } }
@Nonnull static <T> ArrayBinaryHeap<T> heapify(@Nonnull T[] array, @Nonnull Comparator<T> c) { final ArrayBinaryHeap<T> heap = new ArrayBinaryHeap<T>(array, c); for (int i = heap.size / 2; i >= 0; i--) { heap.bubbleDown(i); } return heap; }
public boolean isValidIndex(int index) { return index >= getRootIndex() && index < size; }
void add(@Nonnull T value) { array[lastIndex + 1] = value; bubbleUp(lastIndex + 1); lastIndex++; }
@Nonnull static <T> ArrayBinaryHeap<T> newArrayBinaryHeapWithHeight(int height, @Nonnull Comparator<T> c) { return new ArrayBinaryHeap<T>(height, c); }
private void bubbleUp(int currentIndex) { while (true) { final int parentIndex = getParentIndex(currentIndex); if (isValidIndex(parentIndex)) { final T parent = get(parentIndex); final T current = get(currentIndex); if (comparator.compare(parent, current) < 0) { swap(array, parentIndex, currentIndex); currentIndex = parentIndex; } else { // sorted break; } } else { // no parent break; } } }