Insertion Sort
Overviewโ
Insertion sort builds the sorted result one element at a time, taking the next element and sliding it back into its correct place among those already sorted โ exactly how most people sort a hand of playing cards.
It is O(nยฒ), and it is nonetheless the most used of the elementary sorts, because it is inside almost every production sorting routine. Below roughly 16โ32 elements it beats quicksort and mergesort outright, so those algorithms hand their small subarrays to it.

Core Conceptsโ
| Property | Value |
|---|---|
| Best case | O(n) โ already sorted; one comparison per element, no shifts |
| Average | O(nยฒ) |
| Worst case | O(nยฒ) โ reverse sorted |
| Space | O(1) |
| Stable | Yes |
| Adaptive | Yes, strongly โ O(n + d) where d is the number of inversions |
| Online | Yes โ can sort a stream as elements arrive |
Architecture / Mechanismโ
def insertion_sort(a):
for i in range(1, len(a)):
key = a[i]
j = i - 1
# Shift everything greater than key one position right
while j >= 0 and a[j] > key:
a[j + 1] = a[j]
j -= 1
a[j + 1] = key # drop key into the gap
return a
Note that the inner loop shifts rather than swaps โ one write per displaced element instead of three. That is roughly a 3ร constant-factor win over the swap-based formulation, and it is why insertion sort outperforms bubble sort on the same asymptotics.
Tracing [5, 1, 4, 2]:
| Step | Key | Action | Result |
|---|---|---|---|
| i=1 | 1 | shift 5 right, insert 1 | [1, 5, 4, 2] |
| i=2 | 4 | shift 5 right, insert 4 | [1, 4, 5, 2] |
| i=3 | 2 | shift 5 and 4 right, insert 2 | [1, 2, 4, 5] |
Why "adaptive" is the important wordโ
The inner loop runs only while elements are out of order, so the total work is proportional to the
number of inversions โ pairs that are in the wrong relative order. Formally the cost is
O(n + d), and for nearly-sorted data d is small:
| Input | Inversions | Cost |
|---|---|---|
| Already sorted | 0 | O(n) |
| One element out of place | O(n) | O(n) |
| Every element within k positions of its home | O(nk) | O(nk) |
| Reverse sorted | n(nโ1)/2 | O(nยฒ) |
Real data is very often nearly sorted โ appended log lines, mostly-ordered records, a sorted list with a few recent additions. This property is what Timsort is built to exploit.
Practical Usageโ
# The way insertion sort is actually used: as the base case of a bigger sort
SMALL = 16
def hybrid_sort(a, lo, hi):
if hi - lo < SMALL:
insertion_sort_range(a, lo, hi) # cheap, cache-friendly, no recursion
return
p = partition(a, lo, hi)
hybrid_sort(a, lo, p)
hybrid_sort(a, p + 1, hi)
The reason this wins below the threshold: insertion sort has almost no per-element overhead, does no recursion, allocates nothing, and touches memory strictly sequentially. Quicksort's partitioning and recursion cost more than the quadratic term saves at those sizes.
Binary insertion sort โ using binary search to find the insertion point โ reduces comparisons to O(n log n) but leaves the shifting at O(nยฒ). It helps only when comparisons are much more expensive than moves.
Edge Cases & Pitfallsโ
- Swapping instead of shifting triples the writes for no benefit. Write the shift form.
- The
j >= 0bound must come first in thewhilecondition; reversing the operands indexesa[-1]in Python (silently wrapping to the end) rather than failing. - Use
>not>=in the comparison.>=shifts past equal elements and destroys stability. - It is still O(nยฒ). The adaptivity is real, but on genuinely random input of any size it loses badly โ this is a small-input and nearly-sorted-input tool.
Comparisonsโ
| Insertion | Bubble | Selection | |
|---|---|---|---|
| Best case | O(n) | O(n) | O(nยฒ) |
| Writes on random input | ~nยฒ/4 shifts | ~nยฒ/2 swaps (ร3 writes) | n โ 1 swaps |
| Stable | Yes | Yes | No |
| Adaptive | Strongly | Weakly | No |
| Online | Yes | No | No |
| Used in practice | Yes โ inside Timsort, introsort, pdqsort | No | Rarely |
Referencesโ
- Cormen, Leiserson, Rivest & Stein, Introduction to Algorithms, ยง2.1 โ insertion sort is the book's first algorithm, with its loop invariant proved in full.
- Sedgewick & Wayne, Algorithms, 4th ed., ยง2.1 โ the inversion-count analysis behind the adaptivity claim.
Books & Videosโ
- VisuAlgo โ Sorting โ run it against nearly-sorted input to see the adaptivity directly.
Related Pagesโ
- Choosing a Sort โ Timsort and introsort, where this algorithm actually lives.
- Quicksort โ the sort that delegates its small subarrays here.