public class MergeSort { // Not the actual Merge Sort algorithm: uses "Selection Sort" public static > void sort(T[] A, int s, int e, T[]H) { if ( e - s <= 1 ) // Array of 0 or 1 element return; // No need to sort an array of 1 element... int m = (e+s)/2; // m = middle of s and e /* ------------------------------------------------ "Easy to understand" merge sort: (1) sort the first half of the array A[s]..A[m-1] (2) sort the 2nd half of the array A[m]..A[e-1] (3) merge the 2 sorted portions ------------------------------------------------ */ SelectionSort.sort(A, s, m); printArray(A); SelectionSort.sort(A, m, e); printArray(A); // Merge both sorted arrays merge( A, s, m, e, H); // We have discussed merge() already... } /* -------------------------------------------------------------------- merge(A, s, m, e): merge sorted ranges A[s,m) and A[m,e) Input: A[]: ....... A[s] ... A[m-1] A[m] ... A[e-1] .... <-------------> <-------------> Sorted Sorted Output: A[]: ....... A[s] .................... A[e-1] .... <------------------------------> Sorted -------------------------------------------------------------------- */ public static > void merge(T[] A, int s, int m, int e, T[] H) { int i = s, j = m; // Current elements in left and right portions int k = 0; // Current copy location in help array H while ( i < m || j < e ) // Loop as long as there are unprocessed items { if ( i < m && j < e ) { // Both arrays have unprocessed elements if ( A[i].compareTo(A[j]) <= 0 ) H[k++] = A[i++]; else H[k++] = A[j++]; } else if ( i == m ) // Left part is exhausted (empty) H[k++] = A[j++]; else if ( j == e ) // Right part is exhausted (empty) H[k++] = A[i++]; } // Copy H[ ] back to A[ ] for (i = s, k = 0; i < e; i++, k++) A[i] = H[k]; } public static void printArray(T[] A) { for(int i = 0; i < A.length; i++) System.out.print(A[i] + " "); System.out.println(); } }