cv.cm

Coding · Algorithms

Bubble sort explained: how it works, code and complexity

4 min read

Short answer

Bubble sort is a simple sorting algorithm that repeatedly walks through a list and swaps each pair of adjacent elements that are in the wrong order. After each pass, the largest remaining element has moved, or bubbled, to its final place at the end. It takes O(n²) time in the average and worst case and O(n) on a list that is already sorted, uses O(1) extra space and is stable. It is mainly used for teaching; real programs use the built-in sort.

Open Sort lines

The idea in plain words

Compare the first two elements. If the first is larger, swap them. Then compare the second and third, then the third and fourth, and so on to the end of the list. This is one pass. After the first pass, the largest element is guaranteed to be last, because every comparison carried it one step to the right.

Repeat the pass on the unsorted part, which shrinks by one element each time. If a whole pass makes no swaps, the list is sorted and you can stop early.

Worked example, pass by pass

Sort [5, 1, 4, 2, 8] in ascending order. Elements after the bar are in their final place.

PassComparisons and swapsList after the pass
15↔1 swap, 5↔4 swap, 5↔2 swap, 5 and 8 keep[1, 4, 2, 5, 8] (8 placed)
21 and 4 keep, 4↔2 swap, 4 and 5 keep[1, 2, 4, 5, 8] (5 placed)
31 and 2 keep, 2 and 4 keep, no swaps[1, 2, 4, 5, 8] sorted, stop

Without the early exit, the algorithm would run a fourth pass. With it, three passes are enough here.

Python implementation

def bubble_sort(items):
    """Sort a list in place, ascending. Returns the same list."""
    n = len(items)
    for end in range(n - 1, 0, -1):     # last index of the unsorted part
        swapped = False
        for i in range(end):
            if items[i] > items[i + 1]:  # strict >, keeps equal items in order
                items[i], items[i + 1] = items[i + 1], items[i]
                swapped = True
        if not swapped:                  # no swaps: already sorted
            break
    return items
print(bubble_sort([5, 1, 4, 2, 8]))     # [1, 2, 4, 5, 8]
print(bubble_sort([3, 3, 1]))           # [1, 3, 3]
print(bubble_sort([]))                  # []

The inner loop stops at end because everything after it is already in place. The swapped flag gives the O(n) best case on sorted input.

Time and space complexity

CaseComparisonsTimeReason
Best (already sorted)n − 1O(n)one pass with no swaps, then stop
Average (random order)about n²/2O(n²)about n²/4 swaps on average
Worst (reverse order)n(n − 1)/2O(n²)every comparison is a swap
Extra spaceO(1)sorts in place with a few variables

For 10,000 elements in reverse order, that is almost 50 million comparisons and swaps. The number of swaps always equals the number of inversions, which are pairs of elements that are out of order.

How bubble sort compares with other sorts

AlgorithmBestAverageWorstExtra spaceStable
Bubble sortO(n)O(n²)O(n²)O(1)Yes
Selection sortO(n²)O(n²)O(n²)O(1)No
Insertion sortO(n)O(n²)O(n²)O(1)Yes
Merge sortO(n log n)O(n log n)O(n log n)O(n)Yes
QuicksortO(n log n)O(n log n)O(n²)O(log n)No
HeapsortO(n log n)O(n log n)O(n log n)O(1)No
Timsort (Python sorted)O(n)O(n log n)O(n log n)O(n)Yes

Bubble sort is stable because it only swaps adjacent elements and only when they are strictly out of order, so equal elements never pass each other. Insertion sort has the same complexity and stability but in practice does fewer writes and is faster, which is why it, not bubble sort, is used inside hybrid algorithms such as Timsort.

Variants and common mistakes

  • Cocktail shaker sort goes left-to-right and then right-to-left on alternating passes, which moves small elements at the end (called turtles) to the front faster. It is still O(n²).
  • Comb sort compares elements a gap apart and shrinks the gap, which removes many turtles early; with gap 1 it becomes bubble sort.
  • Odd-even transposition sort compares all odd pairs, then all even pairs, and is used to teach parallel sorting.

When to use bubble sort

Almost never in production code. In Python, call sorted(items) or items.sort(), which use Timsort, run in O(n log n) and are stable. Bubble sort is still useful to know because it is the simplest sort to explain, its proof of correctness is easy to follow, and it is a common first interview or exam question about loops, swaps and complexity.

The one practical advantage is detecting a sorted list in a single O(n) pass, but a plain loop that compares neighbours does that without sorting anything.

FAQ

Is bubble sort stable?

Yes. It only swaps adjacent elements when the left one is strictly greater, so equal elements keep their original order.

What is the time complexity of bubble sort?

O(n²) in the average and worst case. With an early exit when a pass makes no swaps, the best case on already sorted input is O(n).

Why is it called bubble sort?

Large elements move toward the end of the list one swap at a time, like bubbles rising to the surface. After pass k, the k largest elements are in place.

Is bubble sort faster than insertion sort?

No. Both are O(n²), but insertion sort usually does fewer operations and runs faster in practice, especially on nearly sorted data.

Does bubble sort use extra memory?

No. It sorts in place and needs only O(1) extra space for the loop indexes and a temporary value during a swap.

All coding tutorials