Bubble Sort Visualization — Step by Step
Repeatedly steps through the list, compares adjacent elements, and swaps them if out of order.
// quick answer
Bubble Sort is a sorting algorithm that runs in O(n²) time on average with O(1) space. Repeatedly steps through the list, compares adjacent elements, and swaps them if out of order.
How Bubble Sort Works
Bubble Sort works by repeatedly swapping adjacent elements that are in the wrong order. Each pass "bubbles" the largest unsorted element to its correct position. It has early termination when no swaps occur in a pass.
Bubble Sort Step by Step
Step 1: Sweep and swap neighbours
Bubble Sort only ever looks at two elements at a time: a value and its right-hand neighbour. Take [7, 3, 9, 2]. The first pass compares 7 and 3 — out of order, swap — giving [3, 7, 9, 2]. Next it compares 7 and 9: already fine, no swap. Then 9 and 2: swap, giving [3, 7, 2, 9]. Notice that 9, the largest value, was picked up mid-pass and carried all the way to the last index. That drift of the biggest element toward the end is the "bubble" the algorithm is named for.
Step 2: Repeat, but stop one element earlier
After pass one, the largest value is guaranteed to sit at the last index — no later comparison can move it. So pass two only needs to sweep [3, 7, 2]: compare 3 and 7 (fine), then 7 and 2 (swap) → [3, 2, 7, 9]. Pass three sweeps just [3, 2] and swaps to [2, 3, 7, 9]. Each pass locks one more element into the tail, which is why the inner loop bound shrinks by one every iteration (n - i - 1 in the code below).
Why the sorted region grows from the right
The invariant that makes Bubble Sort correct: during a pass, whenever the sweep reaches position j, it is carrying the largest value seen so far in that pass. Whatever is largest in the unsorted zone therefore always reaches the zone's right edge by the end of the pass. Small values are the opposite story — a small element moves at most one slot left per pass (these slow movers are sometimes called "turtles"), which is the intuition for why reverse-sorted input is the worst case: the smallest element needs n−1 full passes to crawl home.
The early exit: a free sortedness check
The one genuinely clever piece of Bubble Sort is the swapped flag. If a complete pass makes zero swaps, every neighbouring pair is in order — and if every neighbour is in order, the whole array is sorted, so the algorithm stops immediately. This gives Bubble Sort a best case of O(n) on already-sorted input: one verification pass and done. It also makes the algorithm *adaptive* — a nearly-sorted array finishes in a few passes rather than the full n−1.
Counting the cost
On random input there is no early exit to save you. Pass one makes n−1 comparisons, pass two makes n−2, down to 1 — a total of n(n−1)/2, which grows as n². Worse, every element travels to its final position one swap at a time, so an element that belongs 50 slots away costs 50 separate writes. That is the structural reason Quick Sort and Merge Sort win: their operations move elements long distances. You can race them and watch the gap open up.
Time & Space Complexity
| Best Case | Average Case | Worst Case | Space |
|---|---|---|---|
| O(n) | O(n²) | O(n²) | O(1) |
Bubble Sort Pseudocode
function bubbleSort(arr):
for i = 0 to n-1:
swapped = false
for j = 0 to n-i-2:
if arr[j] > arr[j+1]:
swap(arr[j], arr[j+1])
swapped = true
mark arr[n-i-1] as sorted
if not swapped: breakPress play in the visualizer above to watch each line execute with live highlighting.
Bubble SortCode in JavaScript, Python & Java
JavaScript
function bubbleSort(arr) {
const n = arr.length;
for (let i = 0; i < n - 1; i++) {
let swapped = false;
for (let j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
swapped = true;
}
}
if (!swapped) break; // early exit: no swaps means sorted
}
return arr;
}Python
def bubble_sort(arr):
n = len(arr)
for i in range(n - 1):
swapped = False
for j in range(n - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
swapped = True
if not swapped: # early exit: no swaps means sorted
break
return arrJava
public static void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
boolean swapped = false;
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
swapped = true;
}
}
if (!swapped) break; // early exit: no swaps means sorted
}
}When to Use Bubble Sort
- Learning and teaching — it is the clearest first sorting algorithm: two nested loops, one visible invariant, and an honest introduction to O(n²).
- Checking sortedness — a single pass with the
swappedflag is an O(n) proof that data is already in order, with the bonus that it fixes the array if it is one swap away. - Nearly-sorted data in tiny scripts — the adaptive early exit makes almost-sorted input cheap, though Insertion Sort is still adaptive *and* faster on the same inputs.
- Avoid it for general-purpose sorting — on random data it does the most swaps of any common quadratic sort; your language's built-in sort will beat it by orders of magnitude past a few dozen elements.
- Avoid it when writes are expensive — its O(n²) swap count is the worst possible fit for flash memory or any medium where writes cost more than reads; Selection Sort makes at most n−1 swaps.
- Curious how bad quadratic really feels? Race it against Merge Sort on identical data.
Bubble Sort — Frequently Asked Questions
Is Bubble Sort stable?
Yes. Bubble Sort only swaps adjacent elements when the left one is strictly greater than the right one, so two equal values are never swapped past each other and keep their original relative order. Stability matters when sorting records by one field while preserving a previous ordering on another field.
What is the time complexity of Bubble Sort?
O(n²) in the average and worst cases, because it performs up to n(n−1)/2 comparisons across its passes. With the swapped-flag optimization, the best case is O(n): already-sorted input is verified in a single pass with zero swaps. Space complexity is O(1) since it sorts in place with only a temporary variable.
Why is it called Bubble Sort?
Because on each pass the largest remaining value rises through the array to its final position at the end, the way a bubble rises through water. A common misconception is that small elements bubble to the front — in the standard left-to-right version they crawl left only one position per pass, which is why they are nicknamed turtles.
Is Bubble Sort used in real life?
Almost never as a production sorting algorithm — library sorts are O(n log n) hybrids that are dramatically faster. Bubble Sort survives as a teaching tool, and its core trick (one pass with a swapped flag) is occasionally useful as a cheap check for whether data is already sorted. If you need a simple quadratic sort in practice, insertion sort is nearly always the better pick.
Bubble Sort vs Insertion Sort — which is faster?
Insertion Sort, in practice. Both are O(n²) with an O(n) best case on sorted input, but Insertion Sort does roughly half the comparisons on random data and shifts elements instead of performing full swaps, so its constant factor is smaller. Bubble Sort has no compensating advantage, which is why Insertion Sort is the quadratic sort that survives inside real libraries.
Compare Bubble Sort
- Bubble Sort vs Selection Sort — when to choose which, head to head
- Bubble Sort vs Insertion Sort — when to choose which, head to head
- Bubble Sort vs Quick Sort — when to choose which, head to head
- Bubble Sort vs Merge Sort — when to choose which, head to head
Related Algorithms
- Selection Sort Visualization — Finds the minimum element and places it at the beginning, repeating for each position.
- Insertion Sort Visualization — Builds the sorted array one item at a time by inserting each element into its correct position.
References & Further Reading
- Wikipedia — Bubble sort
- Knuth, D. E. — The Art of Computer Programming, Vol. 3: Sorting and Searching
- Cormen, Leiserson, Rivest & Stein — Introduction to Algorithms (4th ed., MIT Press)