Data Structures & Algorithms·Reason about cost and structure

Sorting algorithms

Understand how a few classic sorts work so you can choose the built-in sort with confidence.

Intermediate 14 min read Lesson 2 of 300 Challenge included
What you will be able to do
  • Trace insertion sort on a tiny list of five numbers.
  • Describe how merge sort divides and merges the list.
  • Explain what stability means and when it matters.
  • Use the built-in sort instead of hand-rolling one.

In plain English

Complexity measures how much work an algorithm does as the input grows, and Big O notation writes this as O(n²), meaning the work grows with the square of the input, or O(n log n), meaning it grows just a bit faster than linear. Insertion sort takes each element and slides it backward into place, which is simple but slow on large lists. Merge sort splits the list in half, sorts each half, and merges them back together for reliable O(n log n) work. Quicksort picks a pivot and partitions the list into smaller and larger groups before sorting each side. Stability means equal elements keep their original order, which matters when sorting by several keys one after another, and in practice JavaScript built-in sort is the right tool rather than writing your own.

Step by step

  1. 1Trace insertion sort on [5, 2, 9, 1] by sliding each element into place.
  2. 2Split a list in half and describe what merge sort does to each half.
  3. 3Run both sorts and the built-in sort on the same numbers.
  4. 4Check that equal values keep their order in insertion and merge sort.
sorts.jsJavaScript
function insertionSort(values) {
  const items = [...values]
  for (let i = 1; i < items.length; i++) {
    const current = items[i]
    let j = i - 1
    while (j >= 0 && items[j] > current) {
      items[j + 1] = items[j]
      j--
    }
    items[j + 1] = current
  }
  return items
}

function mergeSort(values) {
  if (values.length <= 1) return values
  const mid = Math.floor(values.length / 2)
  const left = mergeSort(values.slice(0, mid))
  const right = mergeSort(values.slice(mid))
  return merge(left, right)
}

function merge(left, right) {
  const result = []
  let i = 0
  let 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))
}

const numbers = [5, 2, 9, 1, 5, 6]
console.log(insertionSort(numbers))
console.log(mergeSort(numbers))
console.log(numbers.sort((a, b) => a - b))

Common mistakes

  • Calling sort() on numbers without a comparator sorts them as strings, so 10 sorts before 2.
  • Confusing stable and unstable sorts is easy, but stability only matters when you sort by several keys in order.
  • Assuming insertion sort is fast for large lists is wrong, because its O(n²) work grows quickly with the input size.
  • Writing your own quicksort for production is usually a mistake, because the built-in sort is already tested and fast.
Your turn

Sort numbers correctly

Easy

Write a one-line call to the built-in sort that sorts an array of numbers in ascending order, then verify it on [10, 2, 1, 5].

JAVASCRIPT · starter
function sortNumbers(values) {
  return values
}
Check your understanding before moving on.
Knowledge checkQuestion 1

Why does [10, 2, 1].sort() in JavaScript put 10 first?

Select an answer to continue
Study tools

Make it yours.

Keep a private note for this lesson, then turn the key ideas into flashcards you can revisit.

Sign in to save notes and flashcards.Both are private to your account and stay with your progress.
Sign in
Finished reading?

Lock in what you just learned.

Mark this lesson complete to save your place and move one step closer to the certificate.

Next: Binary search
Lesson 2 of 300 · 0% of course