package util; public class Sorter { public void sort(int[] array) { if (array == null || array.length <= 1) return; int n = array.length; int[] temp = new int[n]; while (true) { int i = 0; int merges = 0; while (i < n) { // Find first run int left = i; while (i + 1 < n && array[i] <= array[i + 1]) i++; int mid = i; i++; if (i >= n) break; // Find second run while (i + 1 < n && array[i] <= array[i + 1]) i++; int right = i; i++; // Merge both runs merge(array, temp, left, mid, right); merges++; } if (merges == 0) break; } } private void merge(int[] array, int[] temp, int left, int mid, int right) { System.arraycopy(array, left, temp, left, right - left + 1); int i = left; int j = mid + 1; int k = left; while (i <= mid && j <= right) { if (temp[i] <= temp[j]) { array[k++] = temp[i++]; } else { array[k++] = temp[j++]; } } while (i <= mid) array[k++] = temp[i++]; while (j <= right) array[k++] = temp[j++]; } public void mergeSort(int[] array) { if (array == null || array.length <= 1) return; int[] temp = new int[array.length]; mergeSortRecursive(array, temp, 0, array.length - 1); } private void mergeSortRecursive(int[] array, int[] temp, int left, int right) { if (left >= right) return; int mid = (left + right) >>> 1; mergeSortRecursive(array, temp, left, mid); mergeSortRecursive(array, temp, mid + 1, right); mergeDescending(array, temp, left, mid, right); } private void mergeDescending(int[] array, int[] temp, int left, int mid, int right) { System.arraycopy(array, left, temp, left, right - left + 1); int i = left; int j = mid + 1; int k = left; while (i <= mid && j <= right) { if (temp[i] >= temp[j]) { array[k++] = temp[i++]; } else { array[k++] = temp[j++]; } } while (i <= mid) array[k++] = temp[i++]; while (j <= right) array[k++] = temp[j++]; } public void insertionSort(int[] array) { if (array == null || array.length <= 1) return; for (int i = 1; i < array.length; i++) { int key = array[i]; int j = i - 1; while (j >= 0 && array[j] < key) { array[j + 1] = array[j]; j--; } array[j + 1] = key; } } public void optimizedMergeSort(int[] array) { if (array == null || array.length <= 1) return; int[] temp = new int[array.length]; optimizedMergeSortRecursive(array, temp, 0, array.length - 1); } private void optimizedMergeSortRecursive(int[] array, int[] temp, int left, int right) { if (left >= right) return; if (right - left + 1 <= 10) { insertionSortRange(array, left, right); return; } int mid = (left + right) >>> 1; optimizedMergeSortRecursive(array, temp, left, mid); optimizedMergeSortRecursive(array, temp, mid + 1, right); mergeDescending(array, temp, left, mid, right); } private void insertionSortRange(int[] array, int left, int right) { for (int i = left + 1; i <= right; i++) { int key = array[i]; int j = i - 1; while (j >= left && array[j] < key) { array[j + 1] = array[j]; j--; } array[j + 1] = key; } } public void testMergeSort() { int[] array = new int[100]; Util util = new Util(); util.fillArrayRandom(array, 100); Sorter mySorter = new Sorter(); mySorter.mergeSort(array); util.printArray(array); } public void testOptimizedMergeSort() { int[] array = new int[100]; Util util = new Util(); util.fillArrayRandom(array, 100); Sorter mySorter = new Sorter(); mySorter.optimizedMergeSort(array); util.printArray(array); } public static final void main(String[] args) { int[] array = new int[100000000]; Util util = new Util(); util.fillArrayRandom(array, 10000000); Sorter mySorter = new Sorter(); mySorter.sort(array); } }