Skillversitas

Merge Sort

Merge Sort is a divide and conquer sorting algorithm. It splits the array into two halves, sorts each half, then merges them.

Algorithm

  1. Divide: Split the array into two halves.
  2. Conquer: Recursively sort each half.
  3. Combine: Merge the two sorted halves.
def merge_sort(arr):
    if len(arr) <= 1:
        return arr

    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])

    return merge(left, right)

def merge(left, right):
    result = []
    i = j = 0

    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1

    result.extend(left[i:])
    result.extend(right[j:])
    return result

Example

data = [38, 27, 43, 3, 9, 82, 10]
print(merge_sort(data))  # [3, 9, 10, 27, 38, 43, 82]

Visualization

[38, 27, 43, 3, 9, 82, 10]
        /           \
[38, 27, 43, 3]   [9, 82, 10]
   /       \          /    \
[38, 27] [43, 3]   [9, 82] [10]
  / \      / \       / \      |
[38][27] [43][3]   [9][82]   [10]
  \ /      \ /       \ /      |
[27, 38] [3, 43]   [9, 82] [10]
   \       /          \    /
[3, 27, 38, 43]   [9, 10, 82]
        \           /
[3, 9, 10, 27, 38, 43, 82]

In-Place Merge Sort

def merge_sort_inplace(arr, left, right):
    if left < right:
        mid = (left + right) // 2
        merge_sort_inplace(arr, left, mid)
        merge_sort_inplace(arr, mid + 1, right)
        merge(arr, left, mid, right)

def merge(arr, left, mid, right):
    left_arr = arr[left:mid + 1]
    right_arr = arr[mid + 1:right + 1]
    i = j = 0
    k = left

    while i < len(left_arr) and j < len(right_arr):
        if left_arr[i] <= right_arr[j]:
            arr[k] = left_arr[i]
            i += 1
        else:
            arr[k] = right_arr[j]
            j += 1
        k += 1

    while i < len(left_arr):
        arr[k] = left_arr[i]
        i += 1
        k += 1

    while j < len(right_arr):
        arr[k] = right_arr[j]
        j += 1
        k += 1

Time Complexity

Case Time
Best O(n log n)
Average O(n log n)
Worst O(n log n)

Space Complexity

O(n) - requires extra arrays for the merge.

Merge Sort vs Quick Sort

Aspect Merge Sort Quick Sort
Worst case O(n log n) O(n²)
Space O(n) O(log n)
Stable Yes No
Cache Less efficient More efficient

Merge Sort is stable and consistent. Quick Sort is faster on average. Next, let's study Quick Sort.