Bubble Sort Algorithm Explained with Examples

By · · Algorithms

Bubble Sort is probably the first sorting algorithm most of us ever learned. It's simple, intuitive, and kind of beautiful in how straightforward it is. You compare neighbors, swap if they're out of order, and repeat until everything is sorted.

Now, is it the fastest? Not even close. But there are situations where it genuinely makes sense, and understanding it well helps you appreciate why more advanced algorithms exist.

Interactive Visualization

Use the controls below to step through the algorithm or let it play automatically.

name: bubble-sort
input: [5, 3, 8, 1, 2, 7, 4, 6]
speed: 500

How Bubble Sort Actually Works

Think of it like this. You walk through your array from left to right, comparing each pair of adjacent elements. If the left one is bigger than the right one, you swap them. After one full pass, the largest element "bubbles up" to the end of the array.

Then you do it again, but you can skip the last position since it's already sorted. Each pass puts one more element in its correct spot. You keep going until no swaps happen in a pass, which means everything is in order.

Here's a flowchart showing the logic:

Step-by-Step Walkthrough

Let's sort the array [5, 3, 8, 1, 2] and watch what happens at each pass.

Pass 1

We compare every adjacent pair and swap when needed:

[5, 3, 8, 1, 2]  → Compare 5 and 3 → Swap!
[3, 5, 8, 1, 2]  → Compare 5 and 8 → No swap
[3, 5, 8, 1, 2]  → Compare 8 and 1 → Swap!
[3, 5, 1, 8, 2]  → Compare 8 and 2 → Swap!
[3, 5, 1, 2, 8]  ✓ 8 is now in its correct position

Pass 2

We skip the last element since 8 is already placed:

[3, 5, 1, 2, 8]  → Compare 3 and 5 → No swap
[3, 5, 1, 2, 8]  → Compare 5 and 1 → Swap!
[3, 1, 5, 2, 8]  → Compare 5 and 2 → Swap!
[3, 1, 2, 5, 8]  ✓ 5 is now in its correct position

Pass 3

[3, 1, 2, 5, 8]  → Compare 3 and 1 → Swap!
[1, 3, 2, 5, 8]  → Compare 3 and 2 → Swap!
[1, 2, 3, 5, 8]  ✓ 3 is now in its correct position

Pass 4

[1, 2, 3, 5, 8]  → Compare 1 and 2 → No swap
[1, 2, 3, 5, 8]  ✓ No swaps happened, so we're done!

Here's a visual summary of how the sorted portion grows after each pass:

Python Implementation

Here's a clean, well-commented implementation:

def bubble_sort(arr):
    """Sort an array in-place using Bubble Sort."""
    n = len(arr)

    for i in range(n):
        swapped = False

        # Each pass pushes the next largest element to the end,
        # so we shrink the range by i each time
        for j in range(0, n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
                swapped = True

        # If nothing got swapped, the array is already sorted
        if not swapped:
            break

    return arr

And here's a version that prints each pass so you can see what's happening:

def bubble_sort_verbose(arr):
    """Bubble Sort with step-by-step output."""
    n = len(arr)
    print(f"Starting array: {arr}")

    for i in range(n):
        swapped = False

        for j in range(0, n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
                swapped = True

        print(f"After pass {i + 1}: {arr}")

        if not swapped:
            print("No swaps needed. Array is sorted!")
            break

    return arr


# Try it out
numbers = [5, 3, 8, 1, 2]
bubble_sort_verbose(numbers)

Output:

Starting array: [5, 3, 8, 1, 2]
After pass 1: [3, 5, 1, 2, 8]
After pass 2: [3, 1, 2, 5, 8]
After pass 3: [1, 2, 3, 5, 8]
After pass 4: [1, 2, 3, 5, 8]
No swaps needed. Array is sorted!

Time and Space Complexity

Case Time Complexity When it happens
Best O(n) Array is already sorted
Average O(n²) Elements are in random order
Worst O(n²) Array is sorted in reverse
Space O(1) Sorts in-place, no extra memory

The best case O(n) only kicks in because of the swapped optimization. Without that early exit, even a sorted array would take O(n²). So don't skip that check.

When Should You Actually Use Bubble Sort?

Look, in production code you'll almost always reach for your language's built-in sort. But Bubble Sort does have its moments:

Nearly sorted data. If your array is almost in order with just a few elements out of place, Bubble Sort with the early termination flag can finish in close to O(n) time. That's genuinely fast for this specific case.

Small datasets. When you're sorting 10 or 20 items, the overhead of a more complex algorithm like Quick Sort or Merge Sort isn't worth it. Bubble Sort's simplicity wins here.

Teaching and learning. There's no better algorithm for understanding comparisons, swaps, and the concept of algorithm optimization. It's the stepping stone to understanding why O(n log n) algorithms matter.

Memory-constrained environments. It uses O(1) extra space. If you're working on an embedded system where every byte counts, that matters.

Real Problem Examples

  1. Sorting a hand of playing cards. You naturally do something like Bubble Sort when you arrange cards, swapping neighbors until everything lines up.

  2. Detecting if a list is almost sorted. Run one pass of Bubble Sort. If you get zero or very few swaps, the data was nearly sorted. This is a useful check before choosing a sorting strategy.

  3. Simple leaderboard updates. If you have a scoreboard where only one score changed, a single pass of Bubble Sort can fix the ordering in O(n) time.

Wrapping Up

Bubble Sort won't win any speed contests for large datasets. But it's stable, in-place, and dead simple to implement. Understanding it thoroughly makes you better at reasoning about algorithmic efficiency, and that skill transfers to every sorting problem you'll face down the road.

The key optimization to remember is the swapped flag. Without it, you're always doing n² work. With it, you get that sweet O(n) best case for nearly sorted data. Small detail, big difference.