Close
Close Window

«  22.1. Sorting I   ::   Contents

23.1. Sorting II

23.1.1. Merge Sort

A natural approach to problem solving is divide and conquer. To use divide and conquer when sorting, we might consider breaking the list to be sorted into pieces, process the pieces, and then put them back together somehow. One way to do this would be to split the list in half, sort the halves, and then merge the sorted halves together. This is the idea behind merge sort. We give the pseudocode for the process below:

public static void mergesort(T[] values) {
   if (values.length <= 1) return; // base case, array is sorted

   else {
      // split the array into two halves and copy their contents
      left = left half of the items from values;
      right = right half of the items from values;

      // recursively sort the halves
      mergesort(left);
      mergesort(right);

      // merge the halves together and store the result in values
      merge(values, left, right);
   }
}

23.1.1.1. merge()

We first look at the merge operation, which takes two smaller, sorted arrays and combines them into a single larger sorted array. It begins by examining the first record of each smaller array and picks the smaller value as the smallest record overall. This smaller value is then copied into the output array. Merging continues in this way, comparing the next records of the smaller arrays and continually appending the smaller to the output array until no more input records remain:

    private void merge(T[] result, T[] a, T[] b) {
        // Index of next value to compare in a
        int left = 0;

        // Index of next value to compare in b
        int right = 0;

        // Index of next slot to fill in sorted
        int next = 0;

        // Keep comparing values in a and b until we run out of values in one
        // of the arrays
        while (left < a.length && right < b.length) {
            // Move the smaller value to sorted
            if (a[left].compareTo(b[right]) < 0) {
                result[next] = a[left];
                left++;
            } else {
                result[next] = b[right];
                right++;
            }
            next++;
        }

        // If there are values left in a, copy the rest of them to sorted
        for (; left < a.length; left++) {
            result[next] = a[left];
            next++;
        }

        // If there are values left in b, copy the rest of them to sorted
        for (; right < b.length; right++) {
            result[next] = b[right];
            next++;
        }
    }
Settings

Proficient Saving... Error Saving
Server Error
Resubmit

In the worst case, the two halves of the array are of size \(n/2\), so the merge operation requires \(O(n)\) time as there are \(n\) records to be copied.

23.1.1.2. mergesort() implementation

Below is the complete implementation of mergesort:

Note

We use the built-in System.arraycopy() method to copy the values into the smaller left and right arrays. This is an \(O(n)\) operation!

    public void mergesort(T[] values) {
        // Base case:  values contains 0 or 1 int.  Return without
        // doing anything since values is already sorted in that case.
        if (values.length <= 1) {    
            return;
        }
        // Recursive case:  there are at least 2 values, so we need to sort them
        else {
            // Split the array into 2 equal-sized parts
            int middle = values.length / 2;
            T[] left = (T[]) (new Comparable[middle]);
            T[] right = (T[]) (new Comparable[values.length - middle]);
            System.arraycopy(values, 0, left, 0, left.length);
            System.arraycopy(values, middle, right, 0, right.length);
            
            // Recursively sort the halves
            mergesort(left);
            mergesort(right);
            
            // Merge the sorted halves together
            merge(values, left, right);
        }
    }
Settings

Proficient Saving... Error Saving
Server Error
Resubmit

23.1.2. Runtime comparisons between sorting algorithms

Note

We will not cover bubble sort or quick sort this semester – they are listed here for reference.

Sorting Algorithm

Time Complexity

Memory Usage

Selection sort

$O(n^2)$

In-place swaps

Insertion sort

$O(n^2)$

In-place swaps

Bubble sort

$O(n^2)$

In-place swaps

Merge sort

$O(n log n)$

Copies array

Quick sort

$O(n log n)$ on avg.

In-place swaps

   «  22.1. Sorting I   ::   Contents

Close Window