Back to DSA Guide Catalog

Algorithmmedium

Insertion Sort Complete Guide

Insertion sort keeps a growing sorted prefix and inserts each new value into its correct position.

It is especially strong for tiny datasets or nearly sorted input where each insertion shifts very little.

Many high-performance sort implementations still use insertion sort for small partitions.

Typical Complexity Baseline

MetricValue
Complexity Note 1Average/Worst O(n^2)
BestO(n)
SpaceO(1)

Video Explainer

Prefer video learning? This explainer gives a quick visual walkthrough of the core idea before you dive into the detailed sections below.

Sorting Visualizer

Step through Insertion Sort to see how the list changes over time.

Insertion Sort
Insertion SortStep 1 / 39

Start with unsorted values.

9
3
7
1
8
2
6
4
5

Core Concepts

Learn the core building blocks and terminology in one place before comparisons, so the mechanics are clear and duplicates are removed.

Sorted prefix

What it is: Left side is maintained in sorted order.

Why it matters: Sorted prefix is a required building block for understanding how Insertion Sort stays correct and performant on large inputs.

Current key

What it is: Value selected for insertion into sorted prefix.

Why it matters: Current key is a required building block for understanding how Insertion Sort stays correct and performant on large inputs.

Shift loop

What it is: Moves larger values right to make room.

Why it matters: Shift loop is a required building block for understanding how Insertion Sort stays correct and performant on large inputs.

Insert position

What it is: Final slot where the key is placed.

Why it matters: Insert position is a required building block for understanding how Insertion Sort stays correct and performant on large inputs.

Outer pointer

What it is: Advances to next unsorted value.

Why it matters: Outer pointer is a required building block for understanding how Insertion Sort stays correct and performant on large inputs.

Insertion position

What it is: Index where current value belongs in sorted prefix.

Why it matters: Index where current value belongs in sorted prefix. In Insertion Sort, this definition helps you reason about correctness and complexity when inputs scale.

Stable sort

What it is: Equal values preserve original relative order.

Why it matters: Equal values preserve original relative order. In Insertion Sort, this definition helps you reason about correctness and complexity when inputs scale.

Adaptive behavior

What it is: Runs faster when input is partially sorted.

Why it matters: Runs faster when input is partially sorted. In Insertion Sort, this definition helps you reason about correctness and complexity when inputs scale.

In-place sort

What it is: Sorts by mutating original array with O(1) extra space.

Why it matters: Sorts by mutating original array with O(1) extra space. In Insertion Sort, this definition helps you reason about correctness and complexity when inputs scale.

Shift

What it is: Move an element one slot right to open insertion space.

Why it matters: Move an element one slot right to open insertion space. In Insertion Sort, this definition helps you reason about correctness and complexity when inputs scale.

Putting It All Together

This walkthrough connects the core concepts of Insertion Sort into one end-to-end execution flow.

Step 1

Sorted prefix

Left side is maintained in sorted order.

Before

Array

524613
  • Sorted prefix initially [5]

After

Array

254613
  • Sorted prefix length grows to 2

Transition

Pick key=2
Shift larger prefix values right

Why this step matters: Sorted prefix is a required building block for understanding how Insertion Sort stays correct and performant on large inputs.

Step 2

Current key

Value selected for insertion into sorted prefix.

Before

Array

254613
  • Next key=4

After

Array

245613
  • Sorted prefix length grows to 3

Transition

Shift 5 right
Insert 4 in gap

Why this step matters: Current key is a required building block for understanding how Insertion Sort stays correct and performant on large inputs.

Step 3

Shift loop

Moves larger values right to make room.

Before

Array

245613
  • Next key=1

After

Array

124563
  • Large shift on unsorted data

Transition

Shift 6,5,4,2 right
Insert 1 at index 0

Why this step matters: Shift loop is a required building block for understanding how Insertion Sort stays correct and performant on large inputs.

Step 4

Insert position

Final slot where the key is placed.

Before

  • Array nearly sorted
  • Only small displacements remain

After

  • Array sorted
  • Good behavior on near-sorted input

Transition

Final key insertions
Minimal shifts per step

Why this step matters: Insert position is a required building block for understanding how Insertion Sort stays correct and performant on large inputs.

How It Compares

vs Bubble Sort

When to choose this: Choose insertion sort for fewer writes on nearly sorted input.

Tradeoff: Both are O(n^2) worst-case on random/reversed arrays.

vs Merge Sort

When to choose this: Choose insertion sort for small arrays where low overhead matters.

Tradeoff: Merge sort scales better for large input sizes.

vs Quick Sort

When to choose this: Choose insertion sort for tiny partitions in hybrid approaches.

Tradeoff: Quick sort dominates on larger random datasets.

Real-World Stories and Company Examples

Language runtime libraries

Standard library sort implementations often switch to insertion sort on very small partitions.

Takeaway: Simple algorithms can be optimal in specific ranges.

Spreadsheet software

Small row groups and incremental updates benefit from insertion-style behavior.

Takeaway: Nearly sorted data changes are often cheaper than full resorting.

Embedded systems

Firmware code paths with tiny arrays choose insertion sort for minimal implementation overhead.

Takeaway: Operational constraints can favor simplicity and predictability.

Implementation Guide

Take each value, shift larger values right, and insert into the gap.

Complexity: Average/Worst O(n^2), Best O(n), Space O(1)

Insertion sort with shifting

function insertionSort(values: number[]): number[] {
  const sortedValues = [...values]
  for (let insertionIndex = 1; insertionIndex < sortedValues.length; insertionIndex += 1) {
    const currentValue = sortedValues[insertionIndex]
    let compareIndex = insertionIndex - 1

    while (compareIndex >= 0 && sortedValues[compareIndex] > currentValue) {
      sortedValues[compareIndex + 1] = sortedValues[compareIndex]
      compareIndex -= 1
    }

    sortedValues[compareIndex + 1] = currentValue
  }

  return sortedValues
}

Common Problems and Failure Modes

  • Overwriting key value before insertion.
  • Off-by-one errors while shifting values.
  • Using insertion sort on large random datasets.
  • Not handling already sorted input as a fast path mentally.
  • Forgetting stability expectations when customizing comparisons.

Tips and Tricks

  • Think of the left side as always sorted, and insert the next value into that region.
  • Insertion sort is very efficient on nearly sorted input because shifts stay small.
  • Store current value before shifting to avoid overwriting data.
  • Use insertion sort for tiny partitions in hybrid production sorts.

When to Use

Use these signals to decide if this data structure/algorithm is the right fit before implementation.

Real-system usage signals

  • Simple in-place implementation with no extra array allocation.
  • Excellent practical behavior on near-sorted arrays.
  • Common fallback in hybrid sorting strategies.

LeetCode-specific tips (including pattern-identification signals)

  • Identification signal: data is nearly sorted or small; each new item is inserted into prior sorted prefix.
  • Identification signal: prompt hints at online insertion behavior rather than full divide-and-conquer split.
  • If stable in-place simple sorting is acceptable for small n, insertion sort is often right.
  • For Insertion Sort questions, start by naming the core invariant before writing code.
  • Use the constraint section to set time/space target first, then pick the data structure/algorithm.
  • Solve one tiny example by hand and map each transition to your variables before implementing.
  • Run adversarial cases: empty input, duplicates, max-size input, and sorted/reverse patterns when relevant.
  • During interviews, explain why your approach is the right pattern for this prompt, not just why the code works.

LeetCode Progression (Easy to Hard)

Back to DSA Guide Catalog
#ProblemDifficultyTypical Complexity
1Relative Sort ArrayEasyO(n log n)
2Sort an ArrayMediumO(n^2) insertion approach
3Insertion Sort ListMediumO(n^2)
4Sort ColorsMediumO(n) optimal, O(n^2) insertion naive
5Largest NumberMediumO(n log n)
6Wiggle Sort IIMediumO(n log n)
7Sort ListMediumO(n log n) target
8Count of Smaller Numbers After SelfHardO(n log n)
9Reverse PairsHardO(n log n)
10Median of Two Sorted ArraysHardO(log(min(m,n)))