// Divide and conquer strategy. // 1. Divide the unsorted list into two sublists of about half the size. // 2. Divide each of the two sublists recursively until we have list sizes of length 1, in which case the list itself is returned. // 3. Merge the two sublists back into one sorted list. - Show diagram. // Improved runtime because: // 1. A small list will take fewer steps to sort than a large list. // 2. Fewer steps are required to construct a sorted list from two sorted lists than two unsorted lists. // Average and worst case performance - n log n comparisons public class MergeSort { private static int comparisonCount = 0; public static void main(String[] args) { for (int i = 0; i < args.length; i++) { System.out.print(args[i] + " "); } System.out.println(); String[] results = doMergeSort(args, 0, args.length - 1); System.out.println("Comparison Count: " + comparisonCount); System.out.println(); for (int i = 0; i < results.length; i++) { System.out.print(results[i] + " "); } } public static String[] doMergeSort(String[] list, int start, int end) { if (end == start) { return new String[] {list[start]}; } else if (end < start) { return new String[] {}; } int middle = (end + start) / 2; String[] leftList = doMergeSort(list, start, middle); String[] rightList = doMergeSort(list, middle + 1, end); return merge(leftList, rightList); } public static String[] merge(String[] leftList, String[] rightList) { String[] result = new String[leftList.length + rightList.length]; int left = 0, right = 0, resultIndex = 0; while (left < leftList.length && right < rightList.length) { if (leftList[left].compareTo(rightList[right]) <= 0) { result[resultIndex++] = leftList[left++]; } else { result[resultIndex++] = rightList[right++]; } comparisonCount++; } while (left < leftList.length) { result[resultIndex++] = leftList[left++]; } while (right < rightList.length) { result[resultIndex++] = rightList[right++]; } return result; } }