← SciSim / Computer Science

Bubble Sort

⚙️ Tier: HSC / Early Undergraduate
📊 Section 1 — Interactive Simulation
Step 0 / 0
Press Play or Step through Bubble Sort.
0
Comparisons
0
Swaps
0
Step
20
Input n
0
Pass #
Comparing
Swapping
Sorted
Unprocessed
Early-exit optimized
Pseudocode
1procedure BubbleSort(A[0..n-1]): 2 for i ← 0 to n-2 do 3 swapped ← false 4 for j ← 0 to n-i-2 do 5 if A[j] > A[j+1] then 6 swap(A[j], A[j+1]) 7 swapped ← true 8 if not swapped then break // early exit 9 return A
Input Size (n)
n = 20
Preset
Custom Input
Actions
Display Options
Index Labels
Value Labels
Pointer Arrows
Swap Animation
Early-Exit Highlight
💡 Section 2 — The Idea, Step by Step

Start: the playground line-up

Imagine a row of kids who need to stand in order from shortest to tallest. You don't try to fix the whole line at once. You just look at two kids standing next to each other: if the one on the left is taller, the two of them swap places. Then you slide one step to the right and check the next pair. By the time you reach the end of the line, the tallest kid has been carried all the way to the far end — they "bubbled" to the top. That single rule, compare two neighbors and swap them if they're out of order, is the whole of Bubble Sort.

Build: counting the work

Call the number of items $n$. One left-to-right sweep is a pass. Each pass guarantees that the largest remaining value reaches its correct spot at the right end, so the next pass can stop one cell earlier. With $n$ items, the first pass makes $n-1$ comparisons, the next makes $n-2$, and so on down to $1$. For a tiny list of $n=5$ items in the worst order, that's $4+3+2+1 = 10$ comparisons to finish.

The pattern in one line

$$\text{worst-case comparisons} = (n-1)+(n-2)+\cdots+1 = \frac{n(n-1)}{2}$$

Deepen: why it's slow, and one clever escape

That sum grows like $\tfrac{1}{2}n^2$, so we say Bubble Sort runs in $\mathcal{O}(n^2)$ time: double the list and the work roughly quadruples. Every swap fixes exactly one inversion (an out-of-order neighbor pair), so the swap count equals the number of inversions in your data. There is one rescue: keep a swapped flag. If a whole pass makes zero swaps, the list is already in order and you can stop immediately — that turns an already-sorted input into a single $n-1$ comparison sweep, the best case $\mathcal{O}(n)$. The Input Size slider sets $n$, and the Preset menu chooses how scrambled the starting data is.

Try this in the sim above: (1) pick the Reverse sorted preset and watch every single comparison turn into a swap — the slowest case. (2) Pick Already sorted and step through: the early-exit flag halts after just one clean pass. (3) Pick Nearly sorted and count how few passes it takes — proof that the swapped flag rewards almost-ordered data.

📐 Section 3 — Algorithm Analysis & Derivation

Bubble Sort — Origin & History

Bubble Sort is one of the simplest comparison-based sorting algorithms. Though its exact origin is debated, it was formally analyzed by Iverson (1962) and popularized in early computer science curricula. The name derives from the way larger elements "bubble up" to the top of the array. Despite its pedagogical value, it is rarely used in production due to its O(n²) worst-case complexity.

Symbol Table

SymbolMeaningRange
\(n\)Input array size\(\mathbb{Z}^+\)
\(T(n)\)Number of comparisons\([n-1, \frac{n(n-1)}{2}]\)
\(W(n)\)Worst-case comparisons\(\frac{n(n-1)}{2}\)
\(B(n)\)Best-case comparisons (optimized)\(n-1\)
\(i\)Outer loop pass index\(0 \leq i \leq n-2\)
\(j\)Inner loop comparison index\(0 \leq j \leq n-i-2\)
\(S(n)\)Number of swaps (worst case)\(\frac{n(n-1)}{2}\)

Step-by-Step Complexity Derivation

Step 1 — Count inner loop iterations

In pass \(i\) (0-indexed), the inner loop runs from \(j=0\) to \(j = n-i-2\), performing \(n-i-1\) comparisons.

$$\text{Comparisons in pass } i = n - i - 1$$

Step 2 — Sum over all passes (worst case)

$$W(n) = \sum_{i=0}^{n-2}(n-i-1) = \sum_{k=1}^{n-1} k = \frac{(n-1)n}{2}$$

Step 3 — Arithmetic series evaluation

$$\sum_{k=1}^{n-1} k = \frac{(n-1) \cdot n}{2} = \frac{n^2 - n}{2}$$

Step 4 — Asymptotic class

$$W(n) = \frac{n^2-n}{2} \implies \boxed{W(n) = \mathcal{O}(n^2)}$$ The dominant term is \(\frac{n^2}{2}\). The constant \(\frac{1}{2}\) is absorbed by Big-O.

Step 5 — Best case (with early-exit optimization)

If the array is already sorted, the first pass completes with no swaps. The swapped flag triggers an early exit after just one pass of \(n-1\) comparisons:

$$B(n) = n-1 \implies \mathcal{O}(n)$$

Step 6 — Average case

On average over all \(n!\) permutations, each element travels roughly \(\frac{n}{4}\) positions. The expected comparisons and swaps are both \(\Theta(n^2)\):

$$A(n) \approx \frac{n^2}{4} \implies \Theta(n^2)$$

Step 7 — Worst case swaps

Worst case (reverse-sorted input): every comparison results in a swap. Number of swaps equals number of inversions in the input, maximum \(\binom{n}{2}\):

$$S_{\max}(n) = \binom{n}{2} = \frac{n(n-1)}{2} = \Theta(n^2)$$

Step 8 — Space complexity

Bubble sort is in-place. Only a constant number of variables (\(i, j, \text{swapped}, \text{temp}\)) are needed regardless of input size:

$$\text{Space} = \mathcal{O}(1) \text{ auxiliary}$$

Step 9 — Stability

Bubble sort is stable: equal elements are never swapped (the condition is strict \(>\), not \(\geq\)), so their relative order is preserved.

Worked Trace Example (n = 6)

Array: [5, 3, 8, 1, 9, 2]

Pass 0: Compare (5,3)→swap→[3,5,8,1,9,2]; (5,8)→no swap; (8,1)→swap→[3,5,1,8,9,2]; (8,9)→no swap; (9,2)→swap→[3,5,1,8,2,9]. Swaps: 3. Element 9 is now in final position.

Pass 1: Compare (3,5)→no swap; (5,1)→swap→[3,1,5,8,2,9]; (5,8)→no swap; (8,2)→swap→[3,1,5,2,8,9]. Swaps: 2.

Pass 2: Compare (3,1)→swap→[1,3,5,2,8,9]; (3,5)→no swap; (5,2)→swap→[1,3,2,5,8,9]. Swaps: 2.

Pass 3: Compare (1,3)→no swap; (3,2)→swap→[1,2,3,5,8,9]. Swaps: 1.

Pass 4: Compare (1,2)→no swap. swapped=false → early exit!

Final: [1,2,3,5,8,9]. Total comparisons: 15 (passes do 5+4+3+2+1). Total swaps: 8.

References

[1] Cormen, Leiserson, Rivest & Stein — Introduction to Algorithms, MIT Press, 4th ed. 2022, Ch. 2: "Getting Started" (Insertion Sort analysis applies analogously)
[2] Sedgewick & Wayne — Algorithms, 4th ed., Addison-Wesley, 2011, §2.1: "Elementary Sorts"
[3] Knuth — The Art of Computer Programming, Vol. 3: Sorting and Searching, §5.2.2
[4] Dasgupta, Papadimitriou & Vazirani — Algorithms, McGraw-Hill, 2006, Ch. 2
❓ Section 4 — FAQ
⚙️ ConceptualWhy does Bubble Sort work? What invariant does it maintain?
After pass \(i\), the \(i+1\) largest elements are guaranteed to be in their final sorted positions at the end of the array. This is the loop invariant: each pass "bubbles" the current maximum to the rightmost unsorted position by comparing adjacent pairs. The algorithm terminates because each pass shrinks the unsorted region by one element. The key insight is that a single comparison-swap on adjacent elements can only fix one inversion at a time, which is why the worst case requires \(\Theta(n^2)\) operations.
Key takeaway: Each pass guarantees one more element reaches its final position — the algorithm makes exactly \(n-1\) passes in the worst case.
🌍 AppliedWhere does Bubble Sort appear in real systems?
Bubble sort is almost never used in production systems due to its O(n²) complexity. However, its underlying adjacent-comparison-swap idea appears in hardware sorting networks and SIMD parallel sort primitives. It is useful for nearly-sorted data streams (the optimized version exits in O(n)) — bubble sort on such inputs beats Merge Sort's constant factors. It is widely used in education because its behavior is easy to visualize and reason about. Shell Sort is a generalization that extends this idea with gap sequences to achieve near O(n^{3/2}) performance.
Key takeaway: Bubble Sort's only practical niche is nearly-sorted small arrays; everywhere else, use Insertion Sort or Timsort.
🔬 SimulationWhat exactly is the simulation showing?
The array is shown as colored rectangular cells. Blue cells are the two elements currently being compared; orange cells are elements in the process of being swapped. Green cells have reached their final sorted positions and will not be touched again. The pseudocode panel highlights the currently executing line in amber. The step message bar below the canvas explains every operation in plain English. Use ◀ Prev to step backward and observe how comparisons and swaps happen — the comparison and swap counters update in real time.
Key takeaway: Stepping slowly through the simulation lets you verify the loop invariant visually — green cells grow from right to left after each pass.
💡 Non-ObviousWhy is Bubble Sort sometimes faster than expected on nearly-sorted input?
With the early-exit optimization (the swapped flag), if a pass completes with zero swaps, the array is sorted and the algorithm terminates immediately. For a nearly-sorted array with only a few inversions, this can mean just 1–2 passes — making it \(\mathcal{O}(n)\). Insertion Sort has the same property and is generally preferred, but Bubble Sort with early-exit is competitive on this specific input class. This is why benchmarks sometimes show Bubble Sort "winning" when testers accidentally test on nearly-sorted data.
Key takeaway: The early-exit flag transforms Bubble Sort from always-\(\mathcal{O}(n^2)\) to best-case \(\mathcal{O}(n)\) — always implement it.
📐 ComplexityWhy is the worst case exactly \(\frac{n(n-1)}{2}\) comparisons?
In the worst case (reverse-sorted input), no early exit occurs and every inner loop comparison results in a swap. Pass 0 does \(n-1\) comparisons, pass 1 does \(n-2\), …, pass \(n-2\) does 1. This is the arithmetic series \(\sum_{k=1}^{n-1} k = \frac{n(n-1)}{2}\). For \(n=1000\), that is 499,500 comparisons — compare this to Merge Sort's \(n \log_2 n \approx 9966\) comparisons. This factor of ~50× explains why Bubble Sort is unacceptable for large inputs.
Key takeaway: \(\frac{n(n-1)}{2}\) is also the number of inversions in a reverse-sorted array — Bubble Sort does exactly one swap per inversion.
🎓 DeepWhat is the connection between Bubble Sort and the inversion count of a permutation?
An inversion is a pair \((i,j)\) with \(i < j\) but \(A[i] > A[j]\). Every swap in Bubble Sort reduces the inversion count by exactly 1 (it fixes exactly the adjacent pair it swaps). Therefore the total number of swaps equals the number of inversions in the input permutation. The expected number of inversions in a random permutation of \(n\) elements is \(\binom{n}{2}/2 = \frac{n(n-1)}{4}\), giving the average-case \(\Theta(n^2)\) swap count. This connection makes Bubble Sort a useful tool for counting inversions theoretically, and variants like Merge Sort use this to count inversions in \(\mathcal{O}(n \log n)\).
Key takeaway: Swap count = inversion count — this gives a precise, not just asymptotic, analysis of Bubble Sort's behavior on any specific input.

References for Section 3

CLRS — Introduction to Algorithms (4th ed.) — Ch. 2 (loop invariants)
Visualgo — visualgo.net/en/sorting
Abdul Bari — youtube.com/@abdul_bari
MIT 6.006 OCW — ocw.mit.edu/6-006
⚠️ Section 5 — Misconceptions & Common Errors

Sub-block A: Conceptual Misconceptions

❌ Misconception: "Bubble Sort is always O(n²) — there's no way to improve it."
✅ Correction: With the early-exit (swapped flag) optimization, Bubble Sort exits after the first pass that makes no swaps. On an already-sorted array, this gives best-case \(\mathcal{O}(n)\). Without this optimization, yes — even a sorted input takes \(\frac{n(n-1)}{2}\) comparisons. The unoptimized version always runs all \(n-1\) passes regardless of input order.
📖 CLRS 4th ed., Exercise 2.2-2; Sedgewick §2.1 "Sorting"
❌ Misconception: "Bubble Sort is a stable sort only if swaps are done carefully."
✅ Correction: The standard implementation using strict A[j] > A[j+1] (not ≥) is unconditionally stable — equal elements are never swapped, preserving their original order. It is only unstable if you carelessly change the condition to . This stability is a genuine advantage over QuickSort and HeapSort in cases where maintaining relative order of equal elements matters (e.g., multi-key sorting).
📖 Knuth, TAOCP Vol. 3, §5.2.2
❌ Misconception: "Bubble Sort and Selection Sort have the same number of swaps."
✅ Correction: Selection Sort does at most \(n-1\) swaps (one per pass, placing the minimum), while Bubble Sort can do up to \(\frac{n(n-1)}{2}\) swaps. For write-expensive memory (flash storage, EEPROMs), Selection Sort is vastly superior to Bubble Sort. The comparison counts are both \(\frac{n(n-1)}{2}\) in the worst case, but swaps differ dramatically.
📖 Sedgewick & Wayne, §2.1 "Elementary Sorts"

Sub-block B: Common Implementation Errors

❌ Error: Inner loop bound for j in range(n-1) — doesn't shrink the inner loop after each pass.
✅ Correct: for j in range(n-i-1) — the last \(i\) elements are already sorted and don't need rechecking. Without this, the algorithm does \(n \cdot (n-1)\) comparisons instead of \(\frac{n(n-1)}{2}\), doubling the work.
🔍 Students copy "n-1" from the outer loop without realizing the inner bound shrinks each pass.
❌ Error: Placing the early-exit check inside the inner loop: if not swapped: break inside the j-loop.
✅ Correct: The early-exit check must be outside the inner loop (after it completes), checking whether the entire pass made any swaps. Placing it inside exits after the first non-swapping pair, which is incorrect — there may still be unsorted elements later in the pass.
🔍 Students confuse "no swap in this comparison" with "no swap in this entire pass."
❌ Error: Claiming Bubble Sort has O(n²) comparisons but O(n) swaps on average.
✅ Correct: On a random permutation, both comparisons and swaps are \(\Theta(n^2)\). The average number of swaps is exactly \(\frac{n(n-1)}{4}\) (half the inversions in expectation), which is \(\Theta(n^2)\), not \(\mathcal{O}(n)\). Only Selection Sort achieves \(O(n)\) swaps in all cases.
🔍 Students confuse best-case swap count with average-case; best case O(0 swaps) is only for already-sorted input.

References for Section 4

CLRS 4th ed. — Ch. 2 "Getting Started"
Skiena — The Algorithm Design Manual 3rd ed., §4.1
Sedgewick & Wayne — Algorithms 4th ed., §2.1 (algs4.cs.princeton.edu)