Algorithms 101: how to use Merge Sort and Quicksort in JavaScript

Algorithms 101: how to use Merge Sort and Quicksort in JavaScript

8 mins read
Oct 23, 2025
Share
Content
Introduction to sorting algorithms
Merge Sort algorithm
Implementation in JavaScript
Time and space complexity
Comparison with other sorting algorithms
Keep the learning going.
Stability in practice: Why Merge Sort is still beloved
Quicksort algorithm
Implementation in JavaScript
Time Complexity
Comparison with other sorting algorithms
A quick taxonomy of sorting algorithms (what matters and why)
What to learn next
Continue reading about JavaScript

Sorting in programming involves placing elements in a list or an array in a certain order. Efficient sorting is important for optimizing other algorithms that require input data to be in sorted lists.

While you may not be required to implement a sorting algorithm in your day-to-day as a software developer, it’s important to know how some of these algorithms work internally. These are common for coding interviews and make you a more efficient developer.

In today’s article, we will explore two of the most popular sorting algorithms, Merge sort and Quicksort. These are essential to your foundations in computer science and optimization of code.

Today, we will learn:



Crack the front end interview

This path will help you make sure you shake off any cobwebs and make a lasting positive impression on your interviewers. You’ll review all the key concepts you need to be familiar with in CSS, HTML, and JavaScript.

Ace the Front End Interview



Introduction to sorting algorithms#

A sorting algorithm is an algorithm used to reorder items in a list or an array according to a specific requirement. For example, sorting algorithms can organize an array of items from smallest to largest.

An efficient sorting algorithm is important for optimizing the efficiency of other algorithms (such as search and compression algorithms).

Sorting algorithms are made up of a series of instructions. They take an array or list as an input, performs operations, and output a sorted array.

There are a number of popular sorting algorithms. The nine most popular are:

  • Bubble sort
  • Insertion sort
  • Merge sort
  • Quicksort
  • Selection sort
  • Counting sort
  • Bucket sort
  • Radix sort
  • Heapsort
1 / 2

Merge Sort algorithm#

Merge sort is an efficient, general-purpose, comparison-based sorting algorithm. It works by recursively dividing an array into two equal halves, sorting and then merging each sorted half.

Take an array [10, -1, 2, 5, 0, 6, 4, -5]. Here is how merge sort would approach it.

widget

Merge sort and Quicksort implementations are examples of a divide and conquer algorithm. Broadly speaking, a divide and conquer algorithm has the following parts:

  • Divide: This involves dividing the problem into subproblems
  • Conquer: recursively process sub problems until each one is solved
  • Combine: combine solved sub problems to give a solution to the original problem

Merge sort can be used for all sorts of problems. The three most common applications of merge sort are sorting linked lists in O(nLogn)O(nLogn) time, an Inversion Count Problem, and External Sorting.


Implementation in JavaScript#

Below is the code implementation of a Merge sort algorithm in JavaScript. The algorithm consists of two functions:

  • The mergeSort() function, which takes care of partitioning the arrays
  • The merge function, which merges the separate arrays
function mergeSort(array) {
if (array.length === 1) {
return array;
}
const middle = Math.floor(array.length / 2);
const left = array.slice(0, middle);
const right = array.slice(middle);
return merge(
mergeSort(left),
mergeSort(right)
);
}
function merge(left, right) {
let 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));
}

Let’s try to break down what is happening:

  1. If the array has only one element, we return the array and terminate (Base case)
  2. Otherwise, we split the array into two halves that are as equal in length as possible (Divide)
  3. Using recursion, we sort both arrays using the mergeSort() function. (Conquer)
  4. Finally, we merge the two sorted arrays and return the result. (Combine)

So, take the array we used an an example above. Let’s see how we would implement merge sort in JavaScript code.

function mergeSort (unsortedArray) {
if (unsortedArray.length <= 1) {
return unsortedArray;
}
// In order to divide the array in half, we need to find middle
const middle = Math.floor(unsortedArray.length / 2);
const left = unsortedArray.slice(0, middle);
const right = unsortedArray.slice(middle);
// Use recursion to combine the left and right
return merge(
mergeSort(left), mergeSort(right)
);
}

Time and space complexity#

Merge sort has a guaranteed time complexity of O(nlogn)O(nlogn) time, which is significantly faster than the average and worst-case running times of several other sorting algorithms. Merge sort is a stable sort with a space complexity of O(n)O(n).

  • Auxiliary Space: O(n)O(n)
  • Algorithmic Paradigm: Divide and Conquer
  • Sorting in Place: No
  • Stable: Yes

Comparison with other sorting algorithms#

Merge sort is marginally slower than quicksort in practice. It is also not as space-efficient as the in-place implementation of Quicksort. MergeSort is generally preferred over QuickSort for Linked Lists, due to difference in memory allocation.


Keep the learning going.#

Learn algorithms for JavaScript without scrubbing through videos or documentation. Educative’s text-based courses are easy to skim and feature live coding environments, making learning quick and efficient.

Ace the Front End Interview


Stability in practice: Why Merge Sort is still beloved#

A stable sort enables multi-key workflows without rewriting keys. Example: you have an array of {city, joinedAt}. First, stably sort by joinedAt. Next, stably sort by city. The final order is “grouped by city, oldest first,” with no custom comparators or pre-composed keys. That’s a major reason many standard libraries choose stable algorithms (or stable hybrids) for general use.

When to reach for Merge Sort

  • You need stability, and O(n) extra space is acceptable.

  • You’re sorting linked lists (merge can be done in O(1) extra space by pointer weaving).

You want predictable O(n log n) time without worst-case pitfalls.

Quicksort algorithm#

Like Merge Sort, QuickSort is a Divide and Conquer algorithm, but it works a bit differently. Quicksort starts by selecting a pivot element from the array and partitioning the other elements into two sub-arrays, according to whether they are less than or greater than the pivot. The sub-arrays are then sorted recursively.

Quicksort algorithm doesn’t use any extra space, as the sorting is done in-place.

There are several ways that this algorithm can choose a pivot element.

  • Pick first element as pivot
  • Pick last element as pivot
  • Pick a random element as pivot
  • Pick median as pivot

Implementation in JavaScript#

The key process below is our partition function, which chooses our pivot. In this implementation, this is done using the Hoare Partition scheme, which works by initializing two indices that start at the ends of the array. The indices move toward each other until an inversion is found.

An inversion is a pair of elements, one greater than or equal to the pivot, one less than or equal, that are in the wrong order relative to each other. The inverted values are then swapped and the process is repeated.

Picking a good pivot is the key for a fast implementation of Quicksort. In practice, Quicksort algorithms use a randomized pivot, which has an expected time complexity of O(nlogn)O(n log n).

function partitionHoare(array, left, right) {
const pivot = Math.floor(Math.random() * (right - left + 1) + left);
while (left <= right) {
while (array[left] < array[pivot]) {
left++;
}
while (array[right] > array[pivot]) {
right--;
}
if (left <= right) {
[array[left], array[right]] = [array[right], array[left]];
}
}
return left;
}
function quicksort(array, left, right) {
left = left || 0;
right = right || array.length - 1;
const pivot = partitionHoare(array, left, right);
if (left < pivot - 1) {
quicksort(array, left, pivot - 1);
}
if (right > pivot) {
quicksort(array, pivot, right);
}
return array;
}


Time Complexity#

Quicksort algorithm has a time complexity of O(nlogn)O(n log n). In the worst case, this becomes O(n2)O(n2). The space used by Quicksort depends on the version used.

The in-place version of Quicksort has a space complexity of O(logn)O(log n), even in the worst case, while the average-case space complexity is O(n)O(n).O(n)O(n).

  • Algorithmic Paradigm: Divide and Conquer
  • Sorting in Place: Yes
  • Stable: Default is not stable

Comparison with other sorting algorithms#

While the average and best-case run time of Quicksort is equal to that of other algorithms such as Merge Sort, a well-implemented Quicksort will have much lower constant factors than other sorting algorithms.

In practice, Quicksort is often faster than merge sort.

In the case of Quick Sort, in its general form is an in-place sort (i.e. it doesn’t require any extra storage). Merge sort requires O(N)O(N) extra storage, where NN denotes the array size which may be quite large.


A quick taxonomy of sorting algorithms (what matters and why)#

When comparing sorting algorithms, think in four dimensions:

  • Comparison vs. non-comparison: Comparison sorts (e.g., Merge Sort, Quicksort, Heapsort) rely on pairwise comparisons and have a lower bound of Ω(n log n). Non-comparison sorts (Counting, Radix, Bucket) exploit structure in the keys (e.g., small integer ranges or fixed-length digit strings) to beat O(n log n) in practice.

  • Stability: A stable algorithm preserves the relative order of equal keys. This matters when you sort by multiple keys (e.g., sort users by city, then stably by signup date). Merge Sort and Timsort are stable; classic Quicksort and Heapsort are not (though you can engineer stable variants).

  • In-place vs. extra memory: In-place uses O(1) or O(log n) extra space (e.g., Quicksort is in-place; Merge Sort typically uses O(n) extra memory). In-place is great when memory is constrained; extra memory can improve stability and cache locality.

  • Data awareness: Different sorting algorithms shine on different data: nearly sorted arrays, tiny arrays, many equal values, bounded integer keys, etc.

Pocket complexity table (average case)

  • Insertion/Bubble/Selection: O(n²) time, O(1) space; only good for tiny inputs or nearly sorted (Insertion).

  • Merge Sort: O(n log n) time, O(n) space, stable.

  • Quicksort: O(n log n) average, O(n²) worst; O(log n) space (stack), typically fastest in practice, not stable by default.

  • Heapsort: O(n log n) time, O(1) space, not stable; good worst-case guarantees.

  • Counting/Radix/Bucket: near O(n + k) or O(d·(n + b)) depending on key range/base; require structural assumptions.

What to learn next#

Sorting is the basis of many complex programming solutions. Though it may seem like a simple concept, sorting is one of the many types of algorithms tested in coding interview.

In practice, a sorting algorithm’s efficiency or speed may sometimes depend on the type of data-set being sorted. You should look into the following algorithms next:

  • Insertion Sort
  • Bubble Sort
  • Selection Sort
  • Heapsort
  • Bucket Sort

To get started with these concepts, check out Educative’s learning path Ace the Front end Interview. You’ll review all the key concepts you need to be familiar with in CSS, HTML, and JavaScript, practicing and diving deep into dozens of real questions. By the time you’re done, you’ll be able to tackle anything that comes your way on the front-end interviews.

Happy learning!


Continue reading about JavaScript#

Frequently Asked Questions

Which sorting algorithm is best?

Quicksort is renowned for being one of the most efficient sorting algorithms, making it widely used in various applications. The algorithm starts by selecting a pivot number, which serves to partition the data. Numbers smaller than the pivot are placed to its left, while larger numbers are situated to its right.

What sorting algorithm does Python use?

Since Python version 2.3 came out, Timsort has been Python’s default sorting algorithm. Timsort is also used for sorting the arrays of non-primitive types in Java SE 7, as well as in platforms and languages like Android, GNU Octave, V8, Swift, and Rust.


Written By:
Jerry Ejonavi