package net.abhinavsarkar.algorist.sort; import java.util.Arrays; import net.abhinavsarkar.algorist.Sorter; public class HeapSorter implements Sorter { @Override public T[] sort(T[] input, Comparator comparator) { if (input.length <= 1) { return input; } heapify(input, comparator); deheapify(input, comparator); return input; } private void heapify(T[] input, Comparator comparator) { for (int i = (input.length - 1)/2; i >= 0; i--) { bubbleDown(input, i, input.length, comparator); } } private void deheapify(T[] input, Comparator comparator) { for (int i = input.length; i > 1; i--) { swap(input, 0, i - 1); bubbleDown(input, 0, i - 1, comparator); } } private void bubbleDown(T[] input, int index, int size, Comparator comparator) { int maxIdx = index; maxIdx = getMaxIdx(input, index * 2 + 1, maxIdx, size, comparator); maxIdx = getMaxIdx(input, index * 2 + 2, maxIdx, size, comparator); if (index != maxIdx) { swap(input, index, maxIdx); bubbleDown(input, maxIdx, size, comparator); } } private int getMaxIdx(T[] input, int childIndex, int minIndex, int size, Comparator comparator) { return childIndex < size && comparator.compare(input[minIndex], input[childIndex]) < 0 ? childIndex : minIndex; } private void swap(T[] input, int i, int j) { if (i == j) { return; } T temp = input[i]; input[i] = input[j]; input[j] = temp; } public static void main(String[] args) { Sorter sorter = new HeapSorter<>(); String[] sorted = sorter.sort(new String[]{"abhinav", "sarkar", "barista", "jordan", "zebra", "data"}, (s, anotherString) -> anotherString.compareTo(s)); System.out.println(Arrays.toString(sorted)); } }