Bubble Sort
Bubble sort is usually the first sorting algorithm people learn. It does one simple thing, again and again: look at two values that sit next to each other. If they are in the wrong order, swap them. Do this enough times, and the whole array becomes sorted. It is slow for big arrays. But it is the easiest algorithm to understand, so it is the best place to start.
Watch it sort
Press play - or drag the timeline and step through it yourself.18 values, not sorted yet. We walk left to right and compare each pair of neighbours.
Complexity
Think of a line of people
Some people stand in a line. We want them ordered from shortest to tallest. The only move we allow: two people standing next to each other may trade places. So you walk along the line. You look at each pair. If the taller person is on the left, they trade places. When you reach the end of the line, the tallest person is now at the back - they 'bubbled up' to the end. Walk the line again, and the second-tallest lands in place. That is the whole algorithm.
How it works, step by step
Start at the left side. Look at the first two values.
Is the left value bigger than the right one? Swap them. If not, do nothing.
Move one step to the right. Compare the next pair. Keep going to the end of the array.
That was one pass. After it, the biggest value is in the last slot - nothing could stop it on the way there.
Do another pass. The end of the array is already sorted, so each new pass can stop one step earlier.
If a full pass makes zero swaps, the array is already sorted. Stop right away.
The code, in JavaScript
The version from textbooks. Easiest to read. But it always does the full work - even when the array is already sorted.
function bubbleSort(arr) {
const a = [...arr]; // copy, so we don't change the input
for (let i = 0; i < a.length - 1; i++) {
for (let j = 0; j < a.length - 1; j++) {
if (a[j] > a[j + 1]) {
// wrong order → swap the two values
const temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
return a;
}
bubbleSort([5, 1, 4, 2]); // → [1, 2, 4, 5]Dry run: sorting [5, 1, 4, 2]
The same steps the visualizer plays, written as a table. Generated by running the real algorithm - not written by hand.
| Step | Pass | Array | What happened |
|---|---|---|---|
| 1 | 1 | [5, 1, 4, 2] | 5 > 1 - wrong order. Swap them. |
| 2 | 1 | [1, 5, 4, 2] | Swapped 5 and 1. |
| 3 | 1 | [1, 5, 4, 2] | 5 > 4 - wrong order. Swap them. |
| 4 | 1 | [1, 4, 5, 2] | Swapped 5 and 4. |
| 5 | 1 | [1, 4, 5, 2] | 5 > 2 - wrong order. Swap them. |
| 6 | 1 | [1, 4, 2, 5] | Swapped 5 and 2. |
| 7 | 2 | [1, 4, 2, 5] | 1 ≤ 4 - correct order. Leave them, move on. |
| 8 | 2 | [1, 4, 2, 5] | 4 > 2 - wrong order. Swap them. |
| 9 | 2 | [1, 2, 4, 5] | Swapped 4 and 2. |
| 10 | 3 | [1, 2, 4, 5] | 1 ≤ 2 - correct order. Leave them, move on. |
Good choice when…
- You are learning or teaching how sorting works. No other algorithm is this easy to follow.
- The array is very small (about 10 items or fewer). At that size, O(n²) does not hurt.
- The data is already almost sorted, and you use the early-exit version. That case runs in O(n) - even faster than merge sort.
- You want a stable sort in five lines, with no extra memory, and speed does not matter.
Bad choice when…
- The array is big. At 10,000 items, bubble sort may do 100 million comparisons. Merge sort needs about 130,000.
- You are writing real production code. JavaScript's built-in `array.sort()` is stable, fast, and already there.
- Your input often arrives in reverse order. That is the worst case for bubble sort: every pair swaps, every pass.
- You need a predictable running time. Bubble sort can be O(n) or O(n²) - a huge gap.
Common mistakes
- The O(n) best case needs the `swapped` flag. The simple version is O(n²) even on a sorted array. People quote the fast number but write the slow version.
- Forgetting `- i` in the inner loop still sorts correctly - but it re-checks the sorted tail every pass, which is about double the work.
- `[a[j], a[j+1]] = [a[j+1], a[j]]` looks nice, but it creates a small throw-away array on every swap. In a hot loop, a plain temp variable is faster.
- A common JS trap (not only for bubble sort): `[10, 9, 1].sort()` gives `[1, 10, 9]`. The default sort compares values as strings. Always pass `(a, b) => a - b` for numbers.
Bubble Sort vs. its closest relatives
| Algorithm | Best | Average | Worst | Space | Stable |
|---|---|---|---|---|---|
| Bubble Sortthis page | O(n) | O(n²) | O(n²) | O(1) | yes |
| Selection Sort | O(n²) | O(n²) | O(n²) | O(1) | no |
| Insertion Sort | O(n) | O(n²) | O(n²) | O(1) | yes |
| Merge Sort | O(n log n) | O(n log n) | O(n log n) | O(n) | yes |
| Quick Sort | O(n log n) | O(n log n) | O(n²) | O(log n) | no |