Skip to main content

Merge Sort

Idea

  • Uses divide and conquer paradigm
  • Divides array into two halves, recursively sorts them, then merges
  • Stable sorting algorithm that maintains relative order of equal elements
  • Guaranteed O(n log n) performance regardless of input data

Visualization


How It Works

  1. Divide Phase:

    • Recursively divide the array into two halves
    • Continue dividing until each subarray has one element
    • Single element arrays are considered sorted
  2. Merge Phase:

    • Merge pairs of sorted subarrays to create larger sorted arrays
    • Compare elements from both arrays and place smaller one first
    • Continue until all elements are merged
    • Use temporary arrays to store intermediate results
  3. Example Process:

    Original: [38,27,43,3,9,82,10]

    Divide:
    [38,27,43,3] | [9,82,10]
    [38,27] | [43,3] | [9,82] | [10]
    [38] | [27] | [43] | [3] | [9] | [82] | [10]

    Merge:
    [27,38] | [3,43] | [9,82] | [10]
    [3,27,38,43] | [9,10,82]
    [3,9,10,27,38,43,82]

Implementation

public class MergeSort {
public static void mergeSort(int[] arr, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;

// Sort first and second halves
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);

// Merge the sorted halves
merge(arr, left, mid, right);
}
}

private static void merge(int[] arr, int left, int mid, int right) {
// Create temporary arrays
int[] leftArray = new int[mid - left + 1];
int[] rightArray = new int[right - mid];

// Copy data to temporary arrays
for (int i = 0; i < leftArray.length; i++) {
leftArray[i] = arr[left + i];
}
for (int i = 0; i < rightArray.length; i++) {
rightArray[i] = arr[mid + 1 + i];
}

// Merge the temporary arrays back
int i = 0, j = 0, k = left;
while (i < leftArray.length && j < rightArray.length) {
if (leftArray[i] <= rightArray[j]) {
arr[k] = leftArray[i];
i++;
} else {
arr[k] = rightArray[j];
j++;
}
k++;
}

// Copy remaining elements if any
while (i < leftArray.length) {
arr[k] = leftArray[i];
i++;
k++;
}
while (j < rightArray.length) {
arr[k] = rightArray[j];
j++;
k++;
}
}
}

Time and Space Analysis

  • Time Complexity:
    • Best Case: O(n log n)
    • Average Case: O(n log n)
    • Worst Case: O(n log n)
  • Space Complexity: O(n) for temporary arrays

Properties

  • Stable sorting algorithm
  • Not in-place (requires extra space)
  • Divide and conquer algorithm
  • Predictable performance (always O(n log n))
  • Parallelizable (different parts can be sorted concurrently)

Use Cases

  • When stable sort is needed
  • When predictable performance is required
  • External sorting (sorting large files)
  • When data is in linked lists (no random access needed)
  • Parallel processing environments

Advantages

  1. Stable sorting algorithm
  2. Guaranteed O(n log n) performance
  3. Parallelizable
  4. Works well with linked lists

Disadvantages

  1. Requires O(n) extra space
  2. Overkill for small arrays
  3. Not cache friendly in basic implementation

Variants

  • Bottom-up merge sort (iterative version)
  • Natural merge sort
  • Parallel merge sort
  • In-place merge sort (complex but possible)

References