Merge Sort
Merge sort is a divide-and-conquer algorithm that divides the input array into two halves, recursively sorts each half, and then merges the sorted halves to produce the sorted array.
Algorithm Overview
The algorithm works by recursively dividing the array into smaller subarrays until each subarray has only one element, then merging these subarrays back together in sorted order.
Key Features
- Divide and Conquer: Breaks problem into smaller subproblems
- Stable: Maintains relative order of equal elements
- Predictable Performance: Always O(n log n) regardless of input
- Not In-Place: Requires additional memory for merging
- Parallelizable: Subproblems can be solved independently
Time and Space Complexity
- Time Complexity: O(n log n) in all cases (best, average, and worst)
- Space Complexity: O(n) - requires additional space for merging
- Recurrence: T(n) = 2T(n/2) + O(n)
- Depth: log n levels of recursion
Algorithm Steps
- Divide: Split the array into two halves at the midpoint
- Conquer: Recursively sort both halves
- Combine: Merge the two sorted halves into a single sorted array
- Base Case: Arrays with 0 or 1 element are already sorted
Usage Examples
Basic Usage
from algo.algorithms.sorting.merge_sort import merge_sort
# Sort integers
numbers = [64, 34, 25, 12, 22, 11, 90]
sorted_numbers = merge_sort(numbers)
print(sorted_numbers) # [11, 12, 22, 25, 34, 64, 90]
# Sort strings
words = ['banana', 'apple', 'cherry']
sorted_words = merge_sort(words)
print(sorted_words) # ['apple', 'banana', 'cherry']
# Empty array
result = merge_sort([])
print(result) # []
In-Place Sorting
from algo.algorithms.sorting.merge_sort import merge_sort_in_place
# Modify original array
arr = [64, 34, 25, 12]
merge_sort_in_place(arr)
print(arr) # [12, 25, 34, 64]
Educational/Debugging
from algo.algorithms.sorting.merge_sort import merge_sort_verbose
# See step-by-step process
merge_sort_verbose([64, 34, 25, 12])
Output:
Dividing: [64, 34, 25, 12]
Left half: [64, 34]
Right half: [25, 12]
Recursively sorting left half:
Dividing: [64, 34]
Left half: [64]
Right half: [34]
Recursively sorting left half:
Base case: [64] (already sorted)
Recursively sorting right half:
Base case: [34] (already sorted)
Merging [64] and [34]
Merging process:
Comparing 64 > 34: taking 34 from right
Adding remaining 64 from left
Merged result: [34, 64]
Recursively sorting right half:
Dividing: [25, 12]
Left half: [25]
Right half: [12]
Recursively sorting left half:
Base case: [25] (already sorted)
Recursively sorting right half:
Base case: [12] (already sorted)
Merging [25] and [12]
Merging process:
Comparing 25 > 12: taking 12 from right
Adding remaining 25 from left
Merged result: [12, 25]
Merging [34, 64] and [12, 25]
Merging process:
Comparing 34 > 12: taking 12 from right
Comparing 34 > 25: taking 25 from right
Comparing 34 <= 64: taking 34 from left
Adding remaining 64 from left
Merged result: [12, 25, 34, 64]
Edge Cases Handled
# Empty array
result = merge_sort([]) # Returns []
# Single element
result = merge_sort([42]) # Returns [42]
# Already sorted
result = merge_sort([1, 2, 3, 4]) # Returns [1, 2, 3, 4]
# Reverse sorted
result = merge_sort([4, 3, 2, 1]) # Returns [1, 2, 3, 4]
# Duplicates
result = merge_sort([3, 1, 3, 1]) # Returns [1, 1, 3, 3]
API Reference
Merge Sort Algorithm Implementation
Merge sort is a divide-and-conquer algorithm that divides the input array into two halves, recursively sorts each half, and then merges the sorted halves to produce the sorted array.
Time Complexity: O(n log n) in all cases (best, average, and worst)
Space Complexity: O(n) - requires additional space for merging
Stability: Stable (maintains relative order of equal elements)
merge_sort(arr)
Sort an array using the merge sort algorithm.
The algorithm works by recursively dividing the array into smaller subarrays until each subarray has only one element, then merging these subarrays back together in sorted order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arr
|
List[T]
|
List of comparable elements to sort |
required |
Returns:
| Type | Description |
|---|---|
List[T]
|
A new sorted list (does not modify the original array) |
Examples:
merge_sort_in_place(arr)
Sort an array using merge sort algorithm with in-place modification.
This version modifies the original array instead of creating a new one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arr
|
List[T]
|
List of comparable elements to sort |
required |
Returns:
| Type | Description |
|---|---|
List[T]
|
The sorted list (same object as input, modified in-place) |
merge_sort_verbose(arr, depth=0)
Merge sort with detailed step-by-step output for educational purposes.
This version prints each step of the divide-and-conquer process to help understand how the algorithm works.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arr
|
List[T]
|
List of comparable elements to sort |
required |
depth
|
int
|
Current recursion depth (for indentation) |
0
|
Returns:
| Type | Description |
|---|---|
List[T]
|
A new sorted list |