Overview
Merge Sort is an efficient, stable, divide-and-conquer sorting algorithm. It divides the input array into two halves, recursively sorts them, and then merges the two sorted halves. Most implementations produce a stable sort, meaning that the order of equal elements is the same in the input and output.Implementation
How It Works
- Divide: Split the array into two halves
- Conquer: Recursively sort each half
- Combine: Merge the two sorted halves into a single sorted array
- Base Case: Arrays with 0 or 1 elements are already sorted
Merge Sort’s divide-and-conquer approach guarantees O(n log n) performance in all cases, making it highly predictable.
Complexity Analysis
Time Complexity
- Best Case: O(n log n)
- Average Case: O(n log n)
- Worst Case: O(n log n)
- Guaranteed performance regardless of input
Space Complexity
- Space: O(n) - requires additional arrays
- Auxiliary: O(n) - for merging
- Call Stack: O(log n) - for recursion
Usage Example
Visual Example
Let’s trace through sorting[38, 27, 43, 3]:
Characteristics
Stability
Stability
Merge Sort is stable - equal elements maintain their relative order in the output.
In-Place
In-Place
No, standard Merge Sort is not in-place. It requires O(n) additional space for merging. In-place variants exist but are more complex.
Adaptive
Adaptive
Standard Merge Sort is not adaptive - it performs the same number of operations regardless of input order. However, variants can be made adaptive.
Online
Online
No, Merge Sort is not online. It needs access to all elements before sorting.
When to Use
Merge Sort is excellent for large datasets, linked lists, and when stable sorting is required.
- Large datasets where O(n log n) performance is needed
- When worst-case performance guarantees are important
- Sorting linked lists (can be done in-place)
- When stable sorting is required
- External sorting (sorting data that doesn’t fit in memory)
- Parallel processing (divide-and-conquer is easily parallelizable)
- Memory is extremely limited (requires O(n) extra space)
- Sorting small arrays (overhead of recursion)
- In-place sorting is strictly required
Performance Insights
Recursion Tree Analysis
For an array of size n:- Height of tree: log₂(n)
- Work per level: O(n) - merging all elements
- Total work: O(n) × O(log n) = O(n log n)
Code Walkthrough
Helper Function: merge()
merge function combines two sorted arrays into one sorted array by comparing elements from both arrays.
Main Function: mergeSort()
Comparison with Other Sorts
| Algorithm | Best Case | Average Case | Worst Case | Space | Stable | Predictable |
|---|---|---|---|---|---|---|
| Merge Sort | O(n log n) | O(n log n) | O(n log n) | O(n) | Yes | Yes |
| Quick Sort | O(n log n) | O(n log n) | O(n²) | O(log n) | No | No |
| Heap Sort | O(n log n) | O(n log n) | O(n log n) | O(1) | No | Yes |
| Insertion Sort | O(n) | O(n²) | O(n²) | O(1) | Yes | No |
Variants
Bottom-Up Merge Sort: An iterative version that avoids recursion overhead by merging subarrays of size 1, then 2, then 4, etc.Natural Merge Sort: An adaptive variant that takes advantage of existing runs (sorted subsequences) in the input.Tim Sort: A hybrid algorithm (used by Python and Java) that combines Merge Sort with Insertion Sort for better real-world performance.