14.1 How Bubble Sort Works
Bubble sort works in passes. In each pass it walks along the list and, for every pair of neighbouring values, asks one simple question: is the left value bigger than the right value? If yes, the pair is in the wrong order for an ascending sort, so the two values are swapped. If no, the pair is left alone.
- After each pass the largest remaining value "bubbles" up to the end of the list.
- After pass
k, the largestkvalues are guaranteed to be in their final positions. - The list is fully sorted when a complete pass produces no swaps.
- When a question says "Describe how a bubble sort places the data in order. Do not use pseudocode statements", the marks are for the ideas.
- Required ideas: compare adjacent values, swap if in the wrong order, repeat in passes, largest value moves to the end each pass, stop when a pass has no swaps.
- Writing code when the question forbids it earns zero.
How Bubble Sort Works
14.1B Interactive Simulator
Try the bubble sort yourself. Change the array values, then click Start. Use Step for manual control or Play for auto-run. Watch how neighbouring values are compared (rose) and swapped (amber), with sorted elements turning green at the end.
Simulation
Status: Click Start to begin.
Code
1n = len(numbers)2for p in range(n - 1):3 for i in range(n - 1):4 if numbers[i] > numbers[i+1]:5 temp = numbers[i]6 numbers[i] = numbers[i+1]7 numbers[i+1] = temp8# sorted!14.2 Bubble Sort in Python — the Standard Version
The standard bubble sort uses only skills you already have — a list, two for loops, an if statement and a swap. Here is the exam-style implementation:
def bubble_sort(numbers):
n = len(numbers)
for p in range(n - 1): # outer loop: one repeat per pass
for i in range(n - 1): # inner loop: walk along the neighbours
if numbers[i] > numbers[i + 1]:
temp = numbers[i] # three-line swap with a
numbers[i] = numbers[i + 1] # temporary variable
numbers[i + 1] = temp
return numbers- Because if you wrote
numbers[i] = numbers[i + 1]first, the original value ofnumbers[i]would be overwritten and lost forever. - The temporary variable
tempkeeps a copy safe while the exchange happens. - Cambridge expects this explicit three-line swap.
- The inner loop runs
range(n - 1)times, neverrange(n), because the comparison reaches one index ahead (i + 1). - Getting this range wrong is the single most common way to lose marks (or crash) in a bubble sort.
- Two nested for loops, both range(n-1)
- Compare scores[i] > scores[i+1]
- Three-line swap with temp
- Return the sorted list
- Same two-loop structure
- Change the comparison from > to <
- Swap when the left value is SMALLER than the right
- String comparison with > works alphabetically in Python
- Same structure — just the data type changes
- Set a counter to 0 before the loops
- Add 1 inside the if block, after the swap
Standard Implementation
14.3 Tracing Bubble Sort
A bubble sort trace records every comparison, whether it swaps or not. The discipline is simple: write down the pair being compared, decide swap or no swap, then write the full list after that comparison.
- 4 values means 3 comparisons per pass
- Pass 1: (5,3) swap, (5,8) no, (8,2) swap
- Pass 2: (3,5) no, (5,2) swap, (5,8) no
- Pass 3: (3,2) swap, then no more swaps needed
- Four values means three comparisons per pass
- Keep going until a pass would make no swaps
- Pass 3 should have no swaps — confirming sorted
- In a trace, marks are lost for missing rows far more often than for wrong swaps.
- Show every comparison — including ones that make no swap — and copy the full list state on every row.
- Neat, complete, mechanical tracing earns the marks.
Tracing & Optimised Version
14.4 Optimised Bubble Sort — the Early Exit
The standard version keeps making passes even after the list is sorted — pure wasted work. The fix is one simple idea: if a full pass makes no swaps, the list is already sorted, so stop. Cambridge calls this the efficient bubble sort.
- 9618/22 O/N 2022 Q asked candidates to "Write an efficient bubble sort algorithm" for 8 marks.
- The word "efficient" in the question is the trigger: the mark scheme reserves marks specifically for the Boolean flag, resetting it each pass, and the loop that terminates when no swaps occur.
- Writing the basic version caps your marks.
def bubble_sort_optimised(numbers):
n = len(numbers)
swapped = True # forces the loop to run at least once
while swapped == True:
swapped = False # reset at the START of every pass
for i in range(n - 1):
if numbers[i] > numbers[i + 1]:
temp = numbers[i]
numbers[i] = numbers[i + 1]
numbers[i + 1] = temp
swapped = True # a swap happened this pass
return numbersswappedmust start asTrue(so the while loop is entered) and must be reset to False at the start of every pass, not just once before the loop.- Forgetting the reset makes the loop run forever, because
swappedcan never return toFalse.
- Pass 1: swap (2,1), then no more swaps
- Pass 2: no swaps at all
- Pass 2 makes no swaps, so the loop ends
- (a) Already sorted: 1 pass, no swaps, loop ends
- (b) From the trace in 14.3: pass 3 had no swaps
- If the question gives you pseudocode or a code skeleton, follow its structure exactly — do not "improve" it with a flag the question never asked for.
- Use the optimised version only when the question asks for an efficient bubble sort or leaves the design to you.
- Also watch for
while swapped = True(assignment) instead ofwhile swapped == True(comparison) — a classic syntax error.
Tracing & Optimised Version
Swap Mechanics & Common Errors
14.5 Performance of Bubble Sort
| Scenario | Passes | Comparisons | Big O |
|---|---|---|---|
| Best case (already sorted, optimised) | 1 | n - 1 | O(n) |
| Worst case (reverse sorted) | n - 1 | ~(n-1)² | O(n²) |
| Average case | ~n/2 | ~n²/2 | O(n²) |
- The performance of bubble sort depends on both the initial order of the data and the number of items.
- Already-sorted data finishes in 1 pass; reverse-sorted data needs maximum passes.
- Doubling the list roughly quadruples the work (O(n²)).
- For a 2-mark "explain why performance depends on the initial order" question, name both ends: already-sorted data needs only one pass before the early exit stops the sort, while reverse-ordered data forces the maximum number of passes with a swap at every comparison.
- One mark per end.
Performance
14.6 Full Exam-Style Question
Nazifa is writing a program for her school's sports day. The finishing times for one race, in seconds, are stored in a list:
Times = [14.2, 12.8, 15.1, 11.9, 13.5, 12.1, 14.8, 13.0]- Compare adjacent/neighbouring values
- Swap if left is greater than right
- Repeat passes through the list
- Largest value moves to end each pass
- Stop when a pass makes no swaps
BubbleSort(Times) that uses an efficient bubble sort to arrange the contents of Times into ascending order and returns the sorted list. Your function should stop as soon as the list is sorted.- Use a Boolean flag (swapped)
- while swapped == True: loop
- Reset swapped = False at start of each pass
- Set swapped = True when a swap occurs
- Three-line swap with temp
- Return the sorted list
- Nearly-sorted data needs fewer swaps
- A pass with no swaps ends the loop early
Key Points Recap
✓ Key Points Summary
14.7 Practice Tasks
Fifteen exam-style bubble sort tasks. Each shows only the question — click Hint for the thought process, or Help for the worked solution.
- For every bubble sort task, the marker checks: (1) correct nested loops (both range(n-1)), (2) correct comparison (numbers[i] > numbers[i+1]), (3) complete three-line swap with temp, (4) for optimised: Boolean flag + while loop + reset each pass.
- The most common mark loss is using range(n) instead of range(n-1).
Question Bank
Answer all questions, then press Submit Quiz to see your score.
Question 1Multiple Choice
What does bubble sort do in each pass?
Question 2True / False
After pass k, the largest k values are in their final positions.
Question 3Multiple Choice
Why use range(n-1) for the inner loop?
Question 4Multiple Choice
Why does the swap use a temp variable?
Question 5True / False
The optimised version stops when a pass makes no swaps.
Question 6Multiple Choice
What is the Big O of bubble sort (worst case)?
Question 7Multiple Choice
What is the best case for the OPTIMISED bubble sort?
Question 8True / False
To sort descending, change > to < in the comparison.
Question 9Multiple Choice
What happens if swapped is not reset to False each pass?
Question 10Multiple Choice
In a trace table, what must you show?
Question 11True / False
while swapped = True is correct Python.
Question 12Multiple Choice
The standard version always does how many passes?
Answer all 12 questions to enable submission.