Merge Sort Algorithm
An efficient, stable, divide-and-conquer sorting algorithm with O(n log n) time complexity.
Merge Sort Implementation
JavaScript Implementation
function mergeSort(arr) {
// Base case: arrays with 0 or 1 element are already sorted
if (arr.length <= 1) {
return arr;
}
// Split the array into two halves
const middle = Math.floor(arr.length / 2);
const left = arr.slice(0, middle);
const right = arr.slice(middle);
// Recursively sort and merge the two halves
return merge(
mergeSort(left),
mergeSort(right)
);
}
// Helper function to merge two sorted arrays
function merge(left, right) {
let result = [];
let i = 0, j = 0;
// Compare elements from both arrays and add smaller one to result
while (i < left.length && j < right.length) {
if (left[i] < right[j]) {
result.push(left[i++]);
} else {
result.push(right[j++]);
}
}
// Add any remaining elements
return result.concat(left.slice(i)).concat(right.slice(j));
}
// Usage example
let array = [38, 27, 43, 3, 9, 82, 10];
console.log(mergeSort(array)); // [3, 9, 10, 27, 38, 43, 82]
Python Implementation
def merge_sort(arr):
# Base case: arrays with 0 or 1 element are already sorted
if len(arr) <= 1:
return arr
# Split the array into two halves
middle = len(arr) // 2
left = arr[:middle]
right = arr[middle:]
# Recursively sort and merge the two halves
left = merge_sort(left)
right = merge_sort(right)
return merge(left, right)
def merge(left, right):
result = []
i = j = 0
# Compare elements from both arrays and add smaller one to result
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
# Add any remaining elements
result.extend(left[i:])
result.extend(right[j:])
return result
# Test
array = [38, 27, 43, 3, 9, 82, 10]
print(merge_sort(array)) # [3, 9, 10, 27, 38, 43, 82]
C++ Implementation
#include <iostream>
#include <vector>
// Merge two sorted subarrays
std::vector<int> merge(const std::vector<int>& left, const std::vector<int>& right) {
std::vector<int> result;
size_t i = 0, j = 0;
// Compare elements from both arrays and add smaller one to result
while (i < left.size() && j < right.size()) {
if (left[i] < right[j]) {
result.push_back(left[i++]);
} else {
result.push_back(right[j++]);
}
}
// Add any remaining elements
while (i < left.size()) {
result.push_back(left[i++]);
}
while (j < right.size()) {
result.push_back(right[j++]);
}
return result;
}
std::vector<int> mergeSort(const std::vector<int>& arr) {
// Base case: arrays with 0 or 1 element are already sorted
if (arr.size() <= 1) {
return arr;
}
// Split the array into two halves
size_t middle = arr.size() / 2;
std::vector<int> left(arr.begin(), arr.begin() + middle);
std::vector<int> right(arr.begin() + middle, arr.end());
// Recursively sort and merge the two halves
return merge(mergeSort(left), mergeSort(right));
}
int main() {
std::vector<int> array = {38, 27, 43, 3, 9, 82, 10};
std::vector<int> sorted = mergeSort(array);
// Print the sorted array
for (const auto& num : sorted) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
Key Implementation Details:
- Recursive Design: Merge Sort is naturally implemented using recursion, where the base case is an array of size 0 or 1.
- Divide Step: The array is divided into roughly equal halves until reaching the base case.
- Merge Step: The core of the algorithm is the merge function, which combines two sorted arrays into a single sorted array.
- Auxiliary Space: Notice that merge sort creates new arrays in most implementations, using O(n) extra space.
Optimization Techniques:
- Insertion Sort for Small Arrays: For small subarrays (typically less than 10-20 elements), switching to insertion sort can improve performance.
- In-place Merge: Though more complex, in-place merging techniques can reduce the space complexity.
- Avoiding Redundant Copying: Using a pre-allocated auxiliary array that's reused throughout the sort can reduce overhead.
- Early Termination: If the last element of the left subarray is less than or equal to the first element of the right subarray, they're already in order and can be concatenated without merging.