Merge Sort is a classic sorting algorithm that uses the divide and conquer paradigm to efficiently sort an array, this is one of the most asked interview questions.
Steps of Merge Sort
- Divide: Split the array into two halves.
- Conquer: Recursively sort each half.
- Combine: Merge the two sorted halves into a single sorted array.
Detailed Implementation in JavaScript
Let’s implement Merge Sort step-by-step in JavaScript.
Step 1: Splitting the Array
First, we need a function to split the array into two halves.
function mergeSort(arr) {
// Base case: If the array has only one element or is empty
if (arr.length <= 1) {
return arr;
}
// Find the middle index
const mid = Math.floor(arr.length / 2);
// Split the array into left and right halves
const left = arr.slice(0, mid);
const right = arr.slice(mid);
// Recursively sort the left and right halves
return merge(mergeSort(left), mergeSort(right));
}
Step 2: Merging Two Sorted Arrays
Next, we need a function to merge two sorted arrays into one sorted array.
function merge(left, right) {
const result = [];
let leftIndex = 0;
let rightIndex = 0;
// Compare elements from left and right arrays and add the smaller one to the result
while (leftIndex < left.length && rightIndex < right.length) {
if (left[leftIndex] < right[rightIndex]) {
result.push(left[leftIndex]);
leftIndex++;
} else {
result.push(right[rightIndex]);
rightIndex++;
}
}
// Concatenate any remaining elements from the left and right arrays
return result.concat(left.slice(leftIndex))
.concat(right.slice(rightIndex));
}
Full Implementation
Combining the splitting and merging functions, we get the complete implementation of Merge Sort.
function mergeSort(arr) {
if (arr.length <= 1) {
return arr;
}
const mid = Math.floor(arr.length / 2);
const left = arr.slice(0, mid);
const right = arr.slice(mid);
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right) {
const result = [];
let leftIndex = 0;
let rightIndex = 0;
while (leftIndex < left.length && rightIndex < right.length) {
if (left[leftIndex] < right[rightIndex]) {
result.push(left[leftIndex]);
leftIndex++;
} else {
result.push(right[rightIndex]);
rightIndex++;
}
}
return result.concat(left.slice(leftIndex))
.concat(right.slice(rightIndex));
}
// Test the mergeSort function
const array = [34, 7, 23, 32, 5, 62];
const sortedArray = mergeSort(array);
console.log(sortedArray); // Output: [5, 7, 23, 32, 34, 62]
Analyzing Merge Sort
Time Complexity
Merge Sort has a time complexity of O(n log n) in all cases. This is because the array is repeatedly split in half (log n splits) and each split array is processed with a linear time merge operation (n comparisons).
Space Complexity
The space complexity of Merge Sort is O(n) due to the additional space required for the temporary arrays during the merge process. Each recursive call creates new arrays to hold the split halves, leading to additional memory usage.