What is Bubble Sort?
[5, 2, 4, 1], and see exactly why this simplest of sorts is also the slowest.This section has a step-by-step animation in the interactive lesson.
Quick check
Bubble sort's single repeated move is to…
Answer it in the interactive lesson to keep your progress.
How it works, step by step
[5, 2, 4, 1] from scratch:arr[j] > arr[j+1]. If so, swap them using JavaScript's destructuring: [arr[j], arr[j+1]] = [arr[j+1], arr[j]].5 > 2→ swap →[2, 5, 4, 1]5 > 4→ swap →[2, 4, 5, 1]5 > 1→ swap →[2, 4, 1, 5]
5) has bubbled to the end. That tail element is now locked into place.i on each pass. We nest a loop to bubble each remaining element. (The See it step animates every comparison and swap — watch one value lock into place at the right end after each pass.)Bubble Sort in JavaScript
function bubbleSort(list) {
const arr = [...list]; // copy so we don't mutate the caller's array
for (let i = 0; i < arr.length - 1; i++) { // one pass per element
for (let j = 0; j < arr.length - 1 - i; j++) { // ...ignoring the sorted tail
if (arr[j] > arr[j + 1]) { // neighbours out of order?
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; // swap them
}
}
}
return arr;
}
console.log(bubbleSort([5, 2, 4, 1])); // [1, 2, 4, 5]Quick check
After the FIRST full pass of bubble sort on [5, 2, 4, 1], predict which value is guaranteed in place.
Answer it in the interactive lesson to keep your progress.
Where it breaks (and when to use it)
- Skipping the early-exit check. Without checking if any swaps occurred, bubble sort does the full
O(n²)work even on a sorted list. - Shrinking the range wrong. After pass
k, the lastkelements are already sorted. Re-scanning them is redundant. - Scale issues. On large datasets, its quadratic time complexity makes it far too slow.
Take it further — optimized bubble sort
O(n) on sorted inputs.Optimized Bubble Sort in JavaScript
function bubbleSortOptimized(list) {
const arr = [...list];
for (let i = 0; i < arr.length - 1; i++) {
let swapped = false;
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
swapped = true;
}
}
if (!swapped) break; // exit early if no swaps occurred
}
return arr;
}
console.log(bubbleSortOptimized([1, 2, 3, 4])); // [1, 2, 3, 4] (stops after 1 pass)Quick check
With the early-exit flag, predict the cost of bubble-sorting an ALREADY sorted array.
Answer it in the interactive lesson to keep your progress.
How fast is it? (complexity)
O(n²) in the worst and average cases (a pass per element, a scan per pass). Space is O(1) since it sorts in place. With the early-exit flag, it is O(n) on sorted data. It is stable (equal elements keep their order).| Case | Time |
|---|---|
| worst / average | O(n²) |
| already sorted (with early exit) | O(n) |
| space | O(1) in place |
| stable? | yes |
Array.prototype.sort() with no arguments compares as strings, so [10, 9, 2].sort() returns [10, 2, 9] ("10" < "2" alphabetically!). Sorting numbers always needs a comparator: arr.sort((a, b) => a - b).- One move: compare adjacent elements, swap if out of order; largest bubbles to the end.
O(n²)worst/avg,O(1)space, stable. Early-exit makes sorted dataO(n).- Use for learning, not production — reach for quick/merge sort or built-ins at scale (with a numeric comparator!).
O(n log n)), and quick sort (fast in-place average-case champion). Use the switcher at the top to open another strategy, and the See it step to watch it sort.