Merge Sort
Divide-and-conquer sort that recursively splits the array in half, sorts each half, and merges them back in order.
Syntax
mergeSort(arr) Parameters
| Name | Type | Required | Description |
|---|---|---|---|
arr | Array<number> | Yes | The array to sort. Returns a new sorted array (out-of-place). |
Returns
Array<number> — A new sorted array; the original is not mutated.
Examples
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), right.slice(j));
}
function mergeSort(arr) {
if (arr.length <= 1) return arr;
const mid = Math.floor(arr.length / 2);
return merge(mergeSort(arr.slice(0, mid)), mergeSort(arr.slice(mid)));
}
console.log(mergeSort([38, 27, 43, 3, 9, 82, 10]));
Output
[ 3, 9, 10, 27, 38, 43, 82 ]
// Edge case: array of length 0 or 1
function mergeSort(arr) {
if (arr.length <= 1) return arr;
const mid = Math.floor(arr.length / 2);
const merge = (l, r) => {
const out = []; let i = 0, j = 0;
while (i < l.length && j < r.length)
out.push(l[i] <= r[j] ? l[i++] : r[j++]);
return out.concat(l.slice(i), r.slice(j));
};
return merge(mergeSort(arr.slice(0, mid)), mergeSort(arr.slice(mid)));
}
console.log(mergeSort([]));
console.log(mergeSort([7]));
Output
[]
[ 7 ]
Notes
| Case | Time | Space |
|---------|------------|-------|
| Best | O(n log n) | O(n) |
| Average | O(n log n) | O(n) |
| Worst | O(n log n) | O(n) |
Merge sort is **stable** and has guaranteed O(n log n) performance
regardless of input order. The O(n) auxiliary space is its main
drawback for in-memory sorting. It is the preferred algorithm for
linked lists (no random access needed) and for external sorting
(data larger than RAM). JavaScript's `Array.prototype.sort` uses
Timsort, which is a hybrid of merge sort and insertion sort.