Skip to main content
SingaporeComputer ScienceSyllabus dot point

How do simple comparison sorts work, and why are they quadratic?

Implement and trace bubble sort and insertion sort, analyse their complexity, and compare their behaviour on nearly sorted data

A focused answer to the H2 Computing outcome on elementary sorts. Bubble sort and insertion sort, tracing each on an example, their O(n squared) worst case, and why insertion sort excels on nearly sorted input.

Generated by Claude Opus 4.89 min answer

Reviewed by: AI editorial process; not yet individually human-reviewed

Have a quick question? Jump to the Q&A page

Jump to a section
  1. What this dot point is asking
  2. The answer
  3. Examples in context
  4. Try this

What this dot point is asking

SEAB wants you to implement and trace bubble sort and insertion sort, analyse their complexity, and compare how they behave - especially on nearly sorted data. The central idea is that both are simple O(n2)O(n^2) comparison sorts, but insertion sort is adaptive: it does far less work when the input is already close to sorted.

The answer

Bubble sort

Bubble sort repeatedly walks the list comparing adjacent pairs and swapping any that are out of order. After each full pass the largest remaining element has "bubbled" to its correct place at the end:

def bubble_sort(data):
    n = len(data)
    for limit in range(n - 1, 0, -1):
        swapped = False
        for i in range(limit):
            if data[i] > data[i + 1]:
                data[i], data[i + 1] = data[i + 1], data[i]
                swapped = True
        if not swapped:
            break   # already sorted, stop early
    return data

With nn elements it does about n(n1)2\dfrac{n(n-1)}{2} comparisons, so O(n2)O(n^2). The early-exit flag makes its best case O(n)O(n) on already-sorted data.

Insertion sort

Insertion sort builds a sorted region at the front, taking each new element and shifting it left into place:

def insertion_sort(data):
    for i in range(1, len(data)):
        key = data[i]
        j = i - 1
        while j >= 0 and data[j] > key:
            data[j + 1] = data[j]   # shift right
            j = j - 1
        data[j + 1] = key
    return data

Worst case (reverse order) each element shifts past all before it: O(n2)O(n^2). Best case (already sorted) each element needs no shift: O(n)O(n).

Behaviour on nearly sorted data

This is where they differ in practice. Insertion sort is adaptive: if most elements are already near their final places, each does only a few shifts, so the run is close to linear. Bubble sort with the early-exit flag also benefits, but typically performs more swaps. For small or nearly sorted lists, insertion sort is the usual choice and is used as the base case inside faster sorts.

Examples in context

Example 1. Sorting a hand of cards. Most people sort playing cards by insertion: pick up each card and slide it into the right spot among the cards already in order. The everyday method is exactly the insertion sort algorithm, and it feels fast because a hand is small and often nearly sorted.

Example 2. The base case of a fast sort. Production sorting libraries switch to insertion sort once a sublist is small (say under 16 elements), because its low overhead beats the recursion of merge sort or quicksort on tiny inputs. Its adaptive, low-constant behaviour makes it the ideal finisher.

Try this

Q1. After one full pass of bubble sort, what is guaranteed about the list? [1 mark]

  • Cue. The largest unsorted element has moved to its correct final position at the end.

Q2. State the best-case complexity of insertion sort and the input that produces it. [2 marks]

  • Cue. O(n)O(n) - on an already-sorted list, since each element needs no shifting.

Q3. Why is insertion sort preferred over bubble sort for nearly sorted data? [2 marks]

  • Cue. It is adaptive: each element shifts only as far as needed, so few moves occur, approaching a single linear pass.

Exam-style practice questions

Practice questions written in the style of SEAB exam questions on this dot point, with worked answer explainers. The year tag is the paper they imitate, not the source.

Original6 marksTrace one full pass of bubble sort over the list [5,2,9,1,6][5, 2, 9, 1, 6], showing each comparison and any swap, and give the list after the pass. Explain what is guaranteed about the list after the first complete pass.
Show worked answer →

Bubble sort compares adjacent pairs left to right, swapping when the left is larger.

Compare Pair Swap? List after
5 vs 2 (5,2) yes [2, 5, 9, 1, 6]
5 vs 9 (5,9) no [2, 5, 9, 1, 6]
9 vs 1 (9,1) yes [2, 5, 1, 9, 6]
9 vs 6 (9,6) yes [2, 5, 1, 6, 9]

After the first pass the list is [2,5,1,6,9][2, 5, 1, 6, 9].

What is guaranteed: the largest value (99) has "bubbled" to its correct final position at the end of the list. Each subsequent pass fixes the next largest into place.

Markers reward the four adjacent comparisons with correct swaps, the resulting list, and the insight that the largest element is now in its final position.

Original5 marks(a) State the worst-case and best-case time complexity of insertion sort. (b) Explain why insertion sort performs very well on a list that is already nearly sorted. (c) Give one reason insertion sort is often preferred over bubble sort in practice.
Show worked answer →

(a) Worst case O(n2)O(n^2) (a reverse-sorted list, where each new element shifts past all the sorted ones); best case O(n)O(n) (an already-sorted list).

(b) Insertion sort takes each element and shifts it left only as far as needed to sit in order. On nearly sorted data, each element is already close to its place, so very few shifts occur per element - close to a single linear pass.

(c) Insertion sort generally does fewer data movements than bubble sort and is adaptive (fast on nearly sorted input), so it is faster in typical cases and is commonly used for small or almost-sorted lists, including as the base case inside faster sorts.

Markers reward the two complexities, the adaptive behaviour (few shifts when nearly sorted), and a valid practical advantage over bubble sort.

Related dot points