Bubble Sort Visualization
The simplest sort there is: keep swapping neighbors until nothing moves.
Bubble sort is usually the first sorting algorithm anyone learns, and for good reason: the entire idea fits in one sentence. Walk through the array, compare each pair of neighbors, and swap them if they’re out of order. Repeat until a full pass makes no swaps. Large values “bubble up” toward the end of the array, which is exactly what you’ll see in the animation below, where the tallest bars drift right and lock into place one pass at a time.
How it works
Each pass sweeps from left to right, comparing adjacent bars (highlighted as
they’re compared) and swapping any pair that’s in the wrong order. After the
first pass, the largest value is guaranteed to be in its final position at the
far right. Watch it turn green. After the second pass, the second-largest is
locked in, and so on. The unsorted region shrinks by one element per pass,
which is why the code’s outer loop counts end down from a.length - 1.
That guarantee is also the source of bubble sort’s cost: sorting n values takes up to n − 1 passes over a shrinking window, roughly n²/2 comparisons in total. On 100 bars that’s about 5,000 comparisons and, for a random shuffle, around 2,500 swaps. Slow the speed slider down and you can follow every single one.
One classic refinement: if a full pass completes without a single swap, the array is already sorted and you can stop early. That optimization is what makes bubble sort’s best case O(n): a single verifying pass over already-sorted input. The version animated here omits the early-exit flag to keep the code minimal, so it always runs the full O(n²) schedule.
When interviewers ask about it
Nobody ships bubble sort in production, and interviewers know it. It shows up in interviews as a baseline: “implement a simple sort, then tell me what’s wrong with it.” Strong answers name the O(n²) comparison count, note that it’s stable (equal elements never leapfrog each other, because only adjacent out-of-order pairs swap) and in-place (O(1) extra memory), and mention the early-exit trick that makes nearly-sorted input cheap. From there the natural follow-up is “so what would you use instead?”, which is your cue to talk about merge sort or quicksort.
Bubble sort is introduced in Day 5: Multi-Dimensional Arrays and Sorting of the challenge, and the complexity reasoning behind that O(n²) figure is built up in Day 3: Introduction to Time Complexity.
Complexity at a glance
| Best | Average | Worst | Space | Stable |
|---|---|---|---|---|
| O(n) | O(n²) | O(n²) | O(1) | Yes |
The exact code you are watching
This is the real generator that drives the animation above, read from
sort-algorithms.js at build time, so the code and the
visualization can never drift apart. Each yield is one
visual step.
1function* bubbleSort(a) {
2 for (let end = a.length - 1; end > 0; end -= 1) {
3 for (let i = 0; i < end; i += 1) {
4 yield { type: 'compare', i: i, j: i + 1 };
5 if (a[i] > a[i + 1]) {
6 const tmp = a[i];
7 a[i] = a[i + 1];
8 a[i + 1] = tmp;
9 yield { type: 'swap', i: i, j: i + 1 };
10 }
11 }
12 yield { type: 'markSorted', i: end };
13 }
14 yield { type: 'markSorted', i: 0 };
15}