package net.abhinavsarkar.algorist.sort; import java.lang.reflect.Array; import java.util.Arrays; import net.abhinavsarkar.algorist.Sorter; public class MergeSorter implements Sorter { @Override public T[] sort(T[] input, Comparator comparator) { if (input.length == 0) { return input; } return this.sort(input, 0, input.length, comparator); } private T[] sort(T[] input, int start, int end, Comparator comparator) { if (start == end - 1) { T[] output = mkArray(input, 1); output[0] = input[start]; return output; } int half = start + (end - start)/2; T[] left = this.sort(input, start, half, comparator); T[] right = this.sort(input, half, end, comparator); return this.merge(left, right, comparator); } private T[] merge(T[] left, T[] right, Comparator comparator) { T[] output = mkArray(left, left.length + right.length); int i, j, k; i = j = k = 0; while (i < left.length || j < right.length) { if (i >= left.length) { System.arraycopy(right, j, output, j + left.length, right.length - j); break; } if (j >= right.length) { System.arraycopy(left, i, output, i + right.length, left.length - i); break; } output[k++] = comparator.compare(left[i], right[j]) <= 0 ? left[i++] : right[j++]; } return output; } @SuppressWarnings("unchecked") private T[] mkArray(T[] input, int length) { return (T[]) Array.newInstance(input.getClass().getComponentType(), length); } public static void main(String[] args) { Sorter sorter = new MergeSorter<>(); String[] sorted = sorter.sort(new String[]{"abhinav", "sarkar", "barista", "jordan", "data"}, (s, anotherString) -> anotherString.compareTo(s)); System.out.println(Arrays.toString(sorted)); } }