Example. Merge Sort

[comp1110-29]

Merge sort is both an efficient sorting algorithm (although it is not in-place) and a classic example of Divide and Conquer techniques. The algorithm works by dividing the input array in half, recursively sorting each half, and then merging the results. We can write an efficient merge function that combines two sorted lists into a single combined sorted lists. Note that we just loop through both arrays once, so this merge function is more efficient than simply appending the two arrays and then sorting them by other means.

/** * Returns the sorted combination of two * sorted arrays * @param left a sorted array of numbers * @param right a sorted array of numbers * @return a sorted array that contains * exactly the elements of left and right */ int[] merge(int[] left, int[] right) { int leftPos = 0; int rightPos = 0; int[] result = new int[left.length + right.length]; while(leftPos < left.length && rightPos < right.length) { int leftElement = left[leftPos]; int rightElement = right[rightPos]; if(leftElement < rightElement) { result[leftPos + rightPos] = leftElement; leftPos = leftPos + 1; } else { result[leftPos + rightPos] = rightElement; rightPos = rightPos + 1; } } while(leftPos < left.length) { result[leftPos + rightPos] = left[leftPos]; leftPos = leftPos + 1; } while(rightPos < right.length) { result[leftPos + rightPos] = right[rightPos]; rightPos = rightPos + 1; } return result; }

This function consistutes the "combine" step in the divide and conquer strategy. Now all that is left is the "dividing" and "conquering":

/** * Returns a sorted version of the part of the * given array between lower and upper * @param arr an array of integers, PRE: not null * @param lower the lower index of the part of the * array we want to sort, PRE: lower <= upper, * PRE: 0 <= lower < arr.length * @param upper the upper index of the part of the * array we want to sort, PRE: lower <= upper, * PRE: 0 <= upper < arr.length * @return a sorted version of the numbers in the * arr between lower and uppper */ int[] mergeSort(int[] arr, int lower, int upper) { if(arr.length==0) { return arr; } if(upper == lower) { return new int[]{arr[lower]}; } int middle = (lower + upper) / 2; int[] left = mergeSort(arr, lower, middle); int[] right = mergeSort(arr, middle+1, upper); return merge(left, right); }

Note: This functions efficiency can be slightly improved by only allocating one output array and passing it into each function, however this obscures the functionality of the algorithm.

bars magnifying-glass caret-down plus minus arrow-right xmark