Basic

Bubble sort

Bubble sort walks the row, swaps any two neighbors out of order, and repeats until a full pass makes no swap. It is slow but the rule is the clearest there is.

What you will see

16

About 3 min of reading

Try It

Run bubble sort and count its work.

1

Sort a small row with bubble.

def bubble(a): changed = True while changed: changed = False for i in range(len(a) - 1): if a[i] > a[i + 1]: a[i], a[i + 1] = a[i + 1], a[i] changed = True return a print(bubble([5, 3, 1]))

Before you run it, say out loud what it will print. Then open the answer.

What it prints
[1, 3, 5]
2

Count swaps on a reversed row.

nums = [3, 2, 1] swaps = 0 for i in range(len(nums) - 1): if nums[i] > nums[i + 1]: swaps += 1 print(swaps)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
2
3

Show an ordered row needs no swap.

nums = [1, 2, 3] changed = False for i in range(len(nums) - 1): if nums[i] > nums[i + 1]: changed = True print(changed)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
False
4

Print the rough cost of four items.

print(len([1, 2, 3, 4]) ** 2)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
16

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

Bubble sort swaps out-of-order neighbors repeatedly until a full pass makes no swap, costing about n squared steps.
1 walk the row
↓
2 swap out-of-order neighbors
↓
3 repeat until no swap
↓
4 n squared steps
Line by line

Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.

def bubble(a): sets nothing on screen
changed = True sets nothing on screen
while changed: sets nothing on screen
changed = False sets nothing on screen
for i in range(len(a) - 1): sets nothing on screen
if a[i] > a[i + 1]: sets nothing on screen
a[i], a[i + 1] = a[i + 1], a[i] sets nothing on screen
changed = True sets nothing on screen
return a sets nothing on screen
print(bubble([5, 3, 1])) [1, 3, 5]
Why this works
Why it is taught

Bubble sort is the easiest rule to say and draw, so it is used to teach. Real code uses a built-in sort, which is far faster.

n squared is the cost

Each pass looks at every pair, and it may take many passes. For a thousand items that is a million steps, which is why it is only for small rows.

Examples

One pass

nums = [5, 3, 4, 1]
for i in range(len(nums) - 1):
    if nums[i] > nums[i + 1]:
        nums[i], nums[i + 1] = nums[i + 1], nums[i]
print(nums)

One pass moves the largest to the end. The big value bubbles right one step at a time.

Repeat until clean

def bubble(a):
    changed = True
    while changed:
        changed = False
        for i in range(len(a) - 1):
            if a[i] > a[i + 1]:
                a[i], a[i + 1] = a[i + 1], a[i]
                changed = True
    return a
print(bubble([5, 3, 1]))

Keep passing until a pass makes no swap. When nothing swaps, the row is ordered.

Count the swaps

nums = [3, 2, 1]
swaps = 0
for i in range(len(nums) - 1):
    if nums[i] > nums[i + 1]:
        swaps += 1
print(swaps)

Reversed rows need the most swaps. Each pair out of order is one swap.

Already ordered

nums = [1, 2, 3]
changed = False
for i in range(len(nums) - 1):
    if nums[i] > nums[i + 1]:
        changed = True
print(changed)

A clean pass makes no swap, so the sort stops. Ordered input is the fast case.

Neighbors only

nums = [9, 1]
nums[0], nums[1] = nums[1], nums[0]
print(nums)

Bubble only ever swaps neighbors. A far-off value moves one step per pass.

Slow but honest

print(len([1, 2, 3, 4]) ** 2)

Roughly, a row of n items takes n squared steps. That is fine for small rows and bad for big ones.

Stability by hand

rows = [[2, "a"], [2, "b"]]
print(rows[0] > rows[1])

Equal items never swap, so they keep their order. Bubble sort is stable for that reason.

The stop flag

nums = [1, 2, 3]
changed = True
changed = False
for i in range(len(nums) - 1):
    if nums[i] > nums[i + 1]:
        changed = True
print(not changed)

The flag is what lets a sort stop early on ordered data.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Order that is not numbers
Previous Lesson
Order that is not numbers
Next Lesson
Insertion sort
Insertion sort →