Introduction

Sorting rearranges nn records so that their keys are in non-decreasing order. Bubble sort, selection sort and insertion sort are the three simple quadratic methods. Their worst-case quadratic cost is slower than merge sort or heapsort on large inputs, but they are short and in place. Insertion sort is especially suitable for small or nearly sorted arrays and is used inside fast library sorts for small subarrays. They are also the clearest place to learn the properties every sorting question asks about: comparisons, swaps, stability, adaptivity and inversions.

Prerequisites

Core concepts

Properties used to classify sorts

  • In place. uses O(1)O(1) auxiliary memory besides the input array.
  • Stable. records with equal keys keep their original relative order. Stability matters when sorting by one key after another (sort by name, then stably by city, and names stay sorted within each city).
  • Adaptive. runs faster on input that is already nearly sorted.
  • Online. can sort the input as it arrives, one element at a time.
  • Comparison-based. examines keys only by comparing pairs. All three sorts here are comparison-based, so the Ω(nlg⁡n)\Omega(n \lg n) lower bound of Comparison of Sorting Algorithms applies to them.

Inversions

An inversion of A[1..n]A[1..n] is a pair of positions (i,j)(i, j) with i<ji < j and A[i]>A[j]A[i] > A[j]. The number of inversions II measures how unsorted the array is:

  • I=0I = 0 exactly when the array is sorted.
  • I=n(n−1)/2I = n(n-1)/2, the maximum, exactly when the array is in strictly decreasing order.
  • Averaged over all n!n! orderings of distinct keys, I=n(n−1)/4I = n(n-1)/4: each of the (n2)\binom{n}{2} pairs is inverted in exactly half of the orderings.
  • Swapping unequal adjacent keys changes II by exactly 1; swapping equal keys leaves II unchanged. So any sort that only exchanges adjacent elements (bubble sort, insertion sort) performs at least II exchanges, and is Ω(n2)\Omega(n^2) on average.

Example: A=[5,2,4,6,1,3]A = [5, 2, 4, 6, 1, 3] has I=9I = 9 inversions: (5,2)(5,2), (5,4)(5,4), (5,1)(5,1), (5,3)(5,3), (2,1)(2,1), (4,1)(4,1), (4,3)(4,3), (6,1)(6,1), (6,3)(6,3).

Insertion sort

Idea. Keep a sorted prefix A[1..j−1]A[1..j-1]. Insert A[j]A[j] into it by shifting larger elements one place right. Input. A[1..n]A[1..n]. Output. AA sorted in place.

Pseudocode uses 1-based arrays, <- for assignment and A[i..j] for the subarray from position ii to position jj.

Text
INSERTION-SORT(A, n)
    for j <- 2 to n
        key <- A[j]
        i <- j - 1
        while i > 0 and A[i] > key
            A[i + 1] <- A[i]
            i <- i - 1
        A[i + 1] <- key

Invariant. At the start of each iteration, A[1..j−1]A[1..j-1] holds the original first j−1j - 1 elements in sorted order.

Trace on A=[5,2,4,6,1,3]A = [5, 2, 4, 6, 1, 3]:

jjkeyArray after inserting keyShifts
222 5 4 6 1 31
342 4 5 6 1 31
462 4 5 6 1 30
511 2 4 5 6 34
631 2 3 4 5 63

Total shifts =9=I= 9 = I; total key comparisons =12= 12.

Insertion sort passes on 5 2 4 6 1 3
Figure 1. Insertion sort on 5 2 4 6 1 3: one row per value of jj, with the sorted prefix shaded, the key highlighted, and arrows for the elements shifted right.

Analysis. Each shift removes exactly one inversion (the key passes one larger element), so the number of shifts equals II. Each value of jj makes one extra comparison that stops the loop, unless the key reaches position 1. So the number of key comparisons lies between II and I+n−1I + n - 1; in the trace, 9+5−2=129 + 5 - 2 = 12, because two keys (2 and 1) reached the front.

CaseInputComparisonsShiftsTime
Bestalready sortedn−1n - 10Θ(n)\Theta(n)
Worststrictly decreasingn(n−1)/2n(n-1)/2n(n−1)/2n(n-1)/2Θ(n2)\Theta(n^2)
Averagerandom order, distinct keysabout n2/4n^2/4n(n−1)/4n(n-1)/4Θ(n2)\Theta(n^2)

In general the running time is Θ(n+I)\Theta(n + I). Insertion sort is in place, stable (the strict test A[i] > key never moves a key past an equal one), adaptive and online.

Binary insertion sort finds the insertion point by binary search, cutting comparisons to O(nlg⁡n)O(n \lg n) in total. The shifts remain II, so the worst-case time is still Θ(n2)\Theta(n^2).

Selection sort

Idea. For i=1,2,…,n−1i = 1, 2, \ldots, n-1, find the minimum of A[i..n]A[i..n] and exchange it into position ii.

Text
SELECTION-SORT(A, n)
    for i <- 1 to n - 1
        min <- i
        for j <- i + 1 to n
            if A[j] < A[min] then min <- j
        if min != i then exchange A[i] with A[min]

Invariant. A[1..i−1]A[1..i-1] holds the i−1i - 1 smallest elements in sorted order.

Trace on A=[5,2,4,6,1,3]A = [5, 2, 4, 6, 1, 3]: after i=1i = 1: 1 2 4 6 5 3; i=2i = 2: unchanged (2 is already the minimum); i=3i = 3: 1 2 3 6 5 4; i=4i = 4: 1 2 3 4 5 6; i=5i = 5: unchanged. Comparisons 15, exchanges 3.

Analysis.

  • Comparisons are always ∑i=1n−1(n−i)=n(n−1)/2\sum_{i=1}^{n-1}(n - i) = n(n-1)/2, whatever the input. Time is Θ(n2)\Theta(n^2) in the best, worst and average cases: selection sort is not adaptive.
  • Exchanges: at most n−1n - 1, the fewest of the three methods. This makes selection sort a reasonable choice when writing an element is much more expensive than comparing.
  • In place.
  • Not stable in the array form above. Example with keys compared by number only: 2a,2b,12_a, 2_b, 1. At i=1i = 1 the minimum 1 is exchanged with 2a2_a, giving 1,2b,2a1, 2_b, 2_a; the two 2s have changed order. A stable variant inserts the minimum by shifting instead of exchanging, at the cost of Θ(n2)\Theta(n^2) moves.

Bubble sort

Idea. Sweep left to right exchanging adjacent out-of-order pairs. Each pass moves the largest remaining element to the end, like a bubble rising. Stop early if a pass makes no exchange.

Text
BUBBLE-SORT(A, n)
    for pass <- 1 to n - 1
        swapped <- FALSE
        for i <- 1 to n - pass
            if A[i] > A[i + 1]
                exchange A[i] with A[i + 1]
                swapped <- TRUE
        if swapped = FALSE then return

Invariant. After pass pp, the last pp positions hold the pp largest elements in their final order.

Trace on A=[5,2,4,6,1,3]A = [5, 2, 4, 6, 1, 3]:

PassArray after the passComparisonsExchanges
12 4 5 1 3 654
22 4 1 3 5 642
32 1 3 4 5 632
41 2 3 4 5 621
51 2 3 4 5 610

Total: 15 comparisons and 9 exchanges =I= I.

Bubble sort passes on 5 2 4 6 1 3
Figure 2. Bubble sort on 5 2 4 6 1 3: the array after each of the five passes, with the elements fixed at the right end shaded and the exchanged pairs of each pass marked.

Analysis.

  • Exchanges equal II (each adjacent exchange removes one inversion).
  • Passes. An element moves left by at most one position per pass. So the number of passes that make an exchange equals the largest number of greater elements to the left of any element. Here element 1 has four greater elements before it, so passes 1 to 4 exchange, and pass 5 confirms.
  • With the swapped flag: best case (sorted input) is one pass of n−1n - 1 comparisons, Θ(n)\Theta(n). Without the flag, bubble sort always makes n(n−1)/2n(n-1)/2 comparisons.
  • Worst case (decreasing input): n(n−1)/2n(n-1)/2 comparisons and exchanges, Θ(n2)\Theta(n^2). Average Θ(n2)\Theta(n^2).
  • In place and stable (only strictly greater neighbours are exchanged).

A known asymmetry: a small element at the far right ("turtle") needs many passes to reach the front, while a large element at the far left ("rabbit") reaches the end in one pass.

Comparison

PropertyBubble (with flag)SelectionInsertion
Best-case timeΘ(n)\Theta(n)Θ(n2)\Theta(n^2)Θ(n)\Theta(n)
Worst-case timeΘ(n2)\Theta(n^2)Θ(n2)\Theta(n^2)Θ(n2)\Theta(n^2)
Average timeΘ(n2)\Theta(n^2)Θ(n2)\Theta(n^2)Θ(n2)\Theta(n^2)
Comparisons, worstn(n−1)/2n(n-1)/2n(n−1)/2n(n-1)/2 (always)n(n−1)/2n(n-1)/2
Exchanges or shiftsIIat most n−1n - 1II shifts
Auxiliary spaceO(1)O(1)O(1)O(1)O(1)O(1)
Stableyesno (array form)yes
Adaptiveyesnoyes, Θ(n+I)\Theta(n + I)
Onlinenonoyes

Exact counts

  • Insertion sort comparisons, exactly. The stopping comparison is missing only when the key becomes the new minimum, that is when A[j]A[j] is smaller than everything before it (a prefix minimum, j≥2j \ge 2). So comparisons =I+(n−1)−m= I + (n - 1) - m, where mm is the number of prefix minima at positions 2 to nn. In the trace, 2 and 1 are prefix minima: 9+5−2=129 + 5 - 2 = 12. On decreasing input every key is a prefix minimum, giving n(n−1)/2+(n−1)−(n−1)=n(n−1)/2n(n-1)/2 + (n-1) - (n-1) = n(n-1)/2.
  • Selection sort on decreasing input makes only ⌊n/2⌋\lfloor n/2 \rfloor exchanges, not n−1n - 1. For 6 5 4 3 2 1: i=1i = 1 gives 1 5 4 3 2 6, i=2i = 2 gives 1 2 4 3 5 6, i=3i = 3 gives 1 2 3 4 5 6, and i=4,5i = 4, 5 find the minimum already in place. Each exchange fixes two positions, the outer pair.
  • Bubble sort passes, turtle against rabbit. With the flag, 2 3 4 5 6 1 takes 5 passes (the 1 moves one place per pass), while 6 1 2 3 4 5 takes 2 passes (the 6 reaches the end in pass 1, and pass 2 confirms). Both arrays have I=5I = 5, so the exchange counts agree while the pass counts differ.

Edge cases

  • n=0n = 0 or n=1n = 1: all three loops do nothing useful and terminate; the array is trivially sorted.
  • All keys equal: I=0I = 0. Insertion sort and flagged bubble sort take Θ(n)\Theta(n); selection sort still takes Θ(n2)\Theta(n^2) comparisons and makes no exchange (with the min != i test).
  • Changing > to >= in insertion sort or bubble sort destroys stability and adds useless moves of equal keys.
  • An array of distinct keys that becomes sorted when one element is moved dd positions has exactly dd inversions, so insertion sort sorts it in Θ(n+d)\Theta(n + d) time.

Important properties and observations

  • Any algorithm that exchanges only adjacent elements needs at least II exchanges, so it is Ω(n2)\Omega(n^2) in the worst and average cases. Breaking the quadratic barrier requires moving elements over long distances (Shell sort, merge sort, quicksort, heapsort).
  • Insertion sort is the method of choice for small nn and nearly sorted input; hybrid sorts switch to it below a small cut-off.
  • Selection sort minimises writes; insertion sort minimises comparisons on nearly sorted data.
  • After kk passes, bubble sort has placed the kk largest elements and selection sort the kk smallest; insertion sort has sorted the first k+1k + 1 elements (which need not be the smallest).

GATE examination perspective

  • State after kk passes. Be precise about what each algorithm guarantees (largest at the end for bubble, smallest at the front for selection, sorted prefix of original elements for insertion).
  • Counting. swaps of bubble sort and shifts of insertion sort equal the number of inversions; selection sort's comparisons are always n(n−1)/2n(n-1)/2.
  • Stability and in-place questions. bubble and insertion are stable; array selection sort is not; all three are in place.
  • Best case traps. bubble sort is Θ(n)\Theta(n) only with the early-exit flag; selection sort is never better than Θ(n2)\Theta(n^2).
  • Exact-count traps. insertion sort comparisons are I+(n−1)−mI + (n-1) - m; selection sort on decreasing input exchanges ⌊n/2⌋\lfloor n/2 \rfloor times; bubble sort passes depend on how far the smallest elements must travel left, not on II.

Summary

Sources

  1. T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein, Introduction to Algorithms, 3rd ed., MIT Press, 2009: Section 2.1 (insertion sort and loop invariants), Section 2.2 (its analysis), Exercise 2.2-2 (selection sort), Problem 2-2 (bubble sort) and Problem 2-4 (inversions).

Next steps