Merge Sort Algorithm in DSA Javascript - Time & Space Complexity
We want to understand how the time taken by merge sort changes as the list to sort gets bigger.
How does the number of steps grow when the input size increases?
Analyze the time complexity of the following code snippet.
function mergeSort(arr) {
if (arr.length <= 1) return arr;
const mid = Math.floor(arr.length / 2);
const left = mergeSort(arr.slice(0, mid));
const right = mergeSort(arr.slice(mid));
return merge(left, right);
}
function merge(left, right) {
const result = [];
let i = 0, j = 0;
while (i < left.length && j < right.length) {
if (left[i] <= right[j]) result.push(left[i++]);
else result.push(right[j++]);
}
return result.concat(left.slice(i)).concat(right.slice(j));
}
This code splits the array into halves recursively, then merges sorted halves back together.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive splitting and merging of arrays.
- How many times: The array is split about log n times, and merging happens n times at each level.
As the input size doubles, the number of splitting levels increases by one, and merging covers all elements each level.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 * 4 = 40 operations |
| 100 | About 100 * 7 = 700 operations |
| 1000 | About 1000 * 10 = 10,000 operations |
Pattern observation: Operations grow roughly as n times log n, which grows faster than linear but slower than quadratic.
Time Complexity: O(n log n)
This means the time grows a bit faster than the size of the input but much slower than checking every pair.
[X] Wrong: "Merge sort is always slower than simple sorting because it uses recursion."
[OK] Correct: Recursion helps break the problem into smaller parts, making the overall process faster than simple methods like bubble sort.
Understanding merge sort's time complexity shows you can analyze efficient algorithms and explain why they work well for sorting large data.
"What if we changed merge sort to split the array into three parts instead of two? How would the time complexity change?"
Practice
Merge Sort algorithm?Solution
Step 1: Understand the divide and conquer approach
Merge Sort splits the array into two halves recursively until single elements remain.Step 2: Merge sorted halves
It then merges these sorted halves back together to form a sorted array.Final Answer:
Divide the array into halves, sort each half, then merge them -> Option DQuick Check:
Merge Sort = Divide, sort halves, merge [OK]
- Confusing Merge Sort with Bubble Sort
- Thinking Merge Sort uses a pivot like Quick Sort
- Believing Merge Sort sorts in place without extra space
arr into two halves in JavaScript for Merge Sort?Solution
Step 1: Calculate middle index correctly
Use Math.floor to get the middle index for even or odd lengths.Step 2: Use slice to split without modifying original array
Slice(0, mid) gets left half; slice(mid) gets right half correctly.Final Answer:
const mid = Math.floor(arr.length / 2); const left = arr.slice(0, mid); const right = arr.slice(mid); -> Option AQuick Check:
Use Math.floor and slice for splitting [OK]
- Using splice which modifies the original array
- Not flooring the middle index causing float errors
- Swapping left and right halves incorrectly
function mergeSort(arr) {
if (arr.length <= 1) return arr;
const mid = Math.floor(arr.length / 2);
const left = mergeSort(arr.slice(0, mid));
const right = mergeSort(arr.slice(mid));
return merge(left, right);
}
function merge(left, right) {
let result = [];
while (left.length && right.length) {
if (left[0] < right[0]) result.push(left.shift());
else result.push(right.shift());
}
return result.concat(left, right);
}
console.log(mergeSort([4, 1, 3, 2]));Solution
Step 1: Recursively split and sort the array
The array [4,1,3,2] is split into [4,1] and [3,2], then further until single elements.Step 2: Merge sorted halves step-by-step
Merge [4] and [1] to [1,4], merge [3] and [2] to [2,3], then merge [1,4] and [2,3] to [1,2,3,4].Final Answer:
[1, 2, 3, 4] -> Option CQuick Check:
Sorted array = [1, 2, 3, 4] [OK]
- Confusing merge order causing wrong output
- Not handling empty arrays in merge
- Using shift inefficiently causing performance issues
function mergeSort(arr) {
if (arr.length === 1) return arr;
const mid = Math.floor(arr.length / 2);
const left = mergeSort(arr.slice(0, mid));
const right = mergeSort(arr.slice(mid));
return merge(left, right);
}
function merge(left, right) {
let result = [];
while (left.length && right.length) {
if (left[0] < right[0]) result.push(left.shift());
else result.push(right.shift());
}
return result.concat(left, right);
}Solution
Step 1: Check base case condition
Base case returns when array length is 1, but it should also handle empty arrays (length 0) to avoid errors.Step 2: Correct base case to include empty arrays
Change condition to arr.length <= 1 to safely return arrays of length 0 or 1.Final Answer:
Base case should be arr.length <= 1, not arr.length === 1 -> Option AQuick Check:
Base case = arr.length <= 1 [OK]
- Ignoring empty array base case causing stack overflow
- Incorrect mid calculation causing wrong splits
- Misunderstanding shift() usage as a bug
score using Merge Sort. Which modification is needed in the merge function to correctly sort by score?Solution
Step 1: Understand sorting objects by property
Objects cannot be compared directly; comparison must use the numeric propertyscore.Step 2: Modify merge comparison to use
Change condition to comparescoreleft[0].scoreandright[0].scoreto merge correctly.Final Answer:
Compare left[0].score and right[0].score instead of elements directly -> Option BQuick Check:
Compare object properties for sorting [OK]
- Trying to compare objects directly causing NaN or errors
- Using string conversion which breaks numeric order
- Sorting keys separately losing object structure
Ready to prove it?
Pass the test and this pattern moves unknown
