🔒 Pro · Component 2 · 2.3.1 Algorithms
2.3.1c Bubble, Insertion and Merge Sort
OCR H446 · A Level Computer Science · ~22 min read
Notes
Video
Slides
Worksheet
Quiz

Bubble Sort

Bubble sort repeatedly steps through the list, comparing adjacent elements and swapping them if they're in the wrong order. After each pass, the largest unsorted element "bubbles up" to its correct position at the end.

Algorithm

function bubbleSort(arr)
    n ← len(arr)
    for i ← 0 to n - 2        // n-1 passes
        swapped ← false
        for j ← 0 to n - 2 - i  // inner loop shrinks each pass
            if arr[j] > arr[j+1] then
                swap arr[j] and arr[j+1]
                swapped ← true
            endif
        next j
        if swapped = false then break  // early exit if sorted
    next i
    return arr
endfunction

Worked Example

Sort: [5, 3, 8, 1, 4]

PassArray stateSwaps
Pass 1[3, 5, 1, 4, 8]5↔3, 5↔1, 5↔4 → 8 placed
Pass 2[3, 1, 4, 5, 8]5↔1, 5↔4 → 5 placed
Pass 3[1, 3, 4, 5, 8]3↔1 → 4 placed
Pass 4[1, 3, 4, 5, 8]No swaps → early exit

Complexity

CaseComparisonsTimeSpace
Best (already sorted)n-1 (1 pass)O(n)O(1)
Worst (reverse sorted)n(n-1)/2O(n²)O(1)
Averagen(n-1)/4O(n²)O(1)

Stable: Yes — equal elements maintain relative order (swaps only when strictly greater). In-place: Yes — O(1) extra space.

Insertion Sort

Insertion sort builds a sorted portion one element at a time. It takes each element from the unsorted portion and inserts it into its correct position in the sorted portion — like sorting a hand of playing cards.

Algorithm

function insertionSort(arr)
    for i ← 1 to len(arr) - 1
        key ← arr[i]       // element to insert
        j ← i - 1
        while j >= 0 AND arr[j] > key
            arr[j+1] ← arr[j]   // shift right to make space
            j ← j - 1
        endwhile
        arr[j+1] ← key    // insert key in correct position
    next i
    return arr
endfunction

Worked Example

Sort: [5, 2, 4, 6, 1, 3] — sorted portion shown in bold

PasskeyArray after insertion
i=12[2, 5, 4, 6, 1, 3]
i=24[2, 4, 5, 6, 1, 3]
i=36[2, 4, 5, 6, 1, 3]
i=41[1, 2, 4, 5, 6, 3]
i=53[1, 2, 3, 4, 5, 6]

Complexity

CaseComparisonsTimeSpace
Best (already sorted)n-1 (one comparison per element)O(n)O(1)
Worst (reverse sorted)n(n-1)/2O(n²)O(1)
Averagen(n-1)/4O(n²)O(1)

Stable: Yes. In-place: Yes — O(1) extra space. Best sorting algorithm for nearly-sorted data and online sorting (receiving elements one at a time).

Merge Sort

Merge sort is a divide-and-conquer algorithm. It recursively divides the list in half until single elements remain, then merges the halves back together in sorted order.

Phase 1: Divide

function mergeSort(arr)
    if len(arr) <= 1 then return arr    // base case
    mid ← len(arr) DIV 2
    left ← mergeSort(arr[0..mid-1])    // recursive call
    right ← mergeSort(arr[mid..end])   // recursive call
    return merge(left, right)
endfunction

Phase 2: Merge (the key step)

function merge(left, right)
    result ← []
    i ← 0; j ← 0
    while i < len(left) AND j < len(right)
        if left[i] <= right[j] then
            result.append(left[i]); i ← i + 1
        else
            result.append(right[j]); j ← j + 1
        endif
    endwhile
    // append remaining elements
    while i < len(left): result.append(left[i]); i ← i + 1
    while j < len(right): result.append(right[j]); j ← j + 1
    return result
endfunction

Worked Example

Sort: [5, 3, 8, 1, 4, 2]

Divide:         [5, 3, 8, 1, 4, 2]
             [5, 3, 8]    [1, 4, 2]
           [5,3] [8]    [1,4] [2]
           [5][3]        [1][4]

Conquer (merge up):
[5][3] → [3,5]     [1][4] → [1,4]
[3,5][8] → [3,5,8] [1,4][2] → [1,2,4]
[3,5,8] + [1,2,4] → [1,2,3,4,5,8]

Complexity

CaseTimeSpace
BestO(n log n)O(n)
WorstO(n log n)O(n)
AverageO(n log n)O(n)

Stable: Yes (use ≤ in merge comparison). Not in-place: O(n) extra space for temporary arrays during merging. The O(n log n) in ALL cases is merge sort's key advantage.

Why O(n log n) for merge sort?

Dividing in half produces log n levels of recursion (same reasoning as binary search). At each level, the total work done across all merge operations is O(n) (merging n elements total). So total = O(n) × O(log n) = O(n log n).

Comparison Table

PropertyBubble SortInsertion SortMerge Sort
Best caseO(n)O(n)O(n log n)
Worst caseO(n²)O(n²)O(n log n)
Average caseO(n²)O(n²)O(n log n)
Space (extra)O(1) in-placeO(1) in-placeO(n) not in-place
Stable?YesYesYes
Best forEducational/small dataNearly sorted, onlineLarge data, guaranteed O(n log n)
Exam tip: Merge sort is ALWAYS O(n log n) — best, worst, and average. Bubble and insertion sort are O(n²) worst/average but O(n) if already sorted. Merge sort uses O(n) extra space (not in-place); bubble and insertion use O(1) (in-place).
Exam tip: Know how to trace bubble sort (show each pass, elements in sorted position bolded), insertion sort (show key and shifting), and merge sort (draw the divide tree and merge steps). These are classic exam questions.
✓ Notes completed!
Video coming soon
Click to advance · Arrow keys also work
Click slide or press arrow keys to navigate

Worksheet — 2.3.1c Bubble, Insertion & Merge Sort

8 questions · 24 marks · instantly marked

Q1Trace bubble sort on the array [4, 2, 7, 1, 5]. Show each pass, elements swapped, and which element reaches its final position.[4 marks]
✓ Mark scheme
Pass 1: [4,2,7,1,5] → 4↔2 → [2,4,7,1,5] → 4 ok → 7↔1 → [2,4,1,7,5] → 7↔5 → [2,4,1,5,7]. 7 is now in place [1]
Pass 2: [2,4,1,5,7] → 2 ok → 4↔1 → [2,1,4,5,7] → 4 ok → 5 ok. 5 is in place [1]
Pass 3: [2,1,4,5,7] → 2↔1 → [1,2,4,5,7] → 2 ok. 4 in place [1]
Pass 4: [1,2,4,5,7] — no swaps. Early termination. Sorted! [1]
Q2Explain why bubble sort with the swapped flag optimisation achieves O(n) best case rather than O(n²).[2 marks]
✓ Mark scheme
Without the flag: always performs n-1 passes → O(n²) even if already sorted. With the swapped flag: if no swaps occur in a pass, the list is already sorted [1]. The algorithm terminates after just 1 pass (n-1 comparisons), making the best case O(n). This optimisation only helps when the list is already or nearly sorted [1].
Q3Trace insertion sort on the array [3, 1, 4, 1, 5, 2]. Show the key and the array state after each insertion.[3 marks]
✓ Mark scheme
i=1, key=1: shift 3 right → [1,3,4,1,5,2] [0.5]
i=2, key=4: 4>3, insert in place → [1,3,4,1,5,2] [0.5]
i=3, key=1: shift 4,3 right → [1,1,3,4,5,2] [0.5]
i=4, key=5: 5>4, no shift → [1,1,3,4,5,2] [0.5]
i=5, key=2: shift 5,4,3 right → [1,1,2,3,4,5] [0.5]
Final: [1,1,2,3,4,5] [0.5]
Q4Explain why insertion sort is particularly efficient for nearly-sorted data. Use the term 'key' and 'shift' in your answer.[2 marks]
✓ Mark scheme
Each element (key) is compared with elements in the sorted portion. If the key is already in roughly the right place (nearly sorted), very few elements need to be shifted to make room [1]. In the best case, no shifts are needed (key stays in place) — just 1 comparison per element → O(n) total. The more out-of-place elements are, the more shifting required, approaching O(n²) for reverse-sorted [1].
Q5Show the merge sort divide-and-conquer process on the array [8, 3, 5, 1]. Draw all divide and merge steps.[4 marks]
✓ Mark scheme
Divide: [8,3,5,1] → [8,3] and [5,1] [1]
Divide: [8,3] → [8] and [3]; [5,1] → [5] and [1] [1]
Merge: [8]+[3] → [3,8] (compare 8 and 3, take 3 first) [1]
Merge: [5]+[1] → [1,5]; Merge: [3,8]+[1,5] → compare 3 vs 1 (take 1), 3 vs 5 (take 3), 8 vs 5 (take 5), take 8 → [1,3,5,8] [1]
Q6State one advantage and one disadvantage of merge sort compared to bubble sort.[2 marks]
✓ Mark scheme
Advantage: merge sort is O(n log n) in ALL cases (best, worst, average) — significantly faster than bubble sort's O(n²) worst case for large datasets [1]. Disadvantage: merge sort requires O(n) additional space for the temporary arrays used during merging; bubble sort is in-place (O(1) extra space). For memory-constrained systems, this extra space requirement is a drawback [1].
Q7Explain what it means for a sorting algorithm to be 'stable'. Give an example using the array [(A,3), (B,1), (C,3)] where the number is the sort key.[3 marks]
✓ Mark scheme
A stable sort preserves the relative order of elements with equal keys [1]. In [(A,3), (B,1), (C,3)], sorted by key: both (A,3) and (C,3) have key 3. A stable sort guarantees (A,3) appears before (C,3) in the output, since (A,3) came first in the original [1]. Output of stable sort: [(B,1), (A,3), (C,3)]. Bubble, insertion, and merge sort are all stable. An unstable sort might output [(B,1), (C,3), (A,3)] — permissible if keys match, but relative order is not preserved [1].
Q8A student has a list of 1,000,000 nearly-sorted records. Which sorting algorithm (bubble, insertion, or merge sort) would you recommend? Justify using time and space complexity.[4 marks]
✓ Mark scheme
Recommended: insertion sort [1]. Reason: for nearly-sorted data, insertion sort approaches O(n) — each element requires very few shifts as it's close to its correct position. This is the best case for insertion sort [1]. Merge sort: always O(n log n) regardless of input order — cannot exploit nearly-sorted structure. Also requires O(n) = O(1,000,000) extra space [1]. Bubble sort: same O(n) best case as insertion sort with the swapped flag, but makes unnecessary comparisons within each pass. Insertion sort is generally preferred over bubble sort in practice. For memory-constrained systems, insertion sort (O(1) space) is preferable to merge sort (O(n) space) [1].
Topic Quiz
1 of 15
You scored
out of 15
🎯

Mini Test — 2.3.1c Sorting Algorithms

  • 10 questions · 10 marks · 10 minutes
  • 5 MCQ + 5 short answer
Card 1 of 15
Click to reveal
🎉
Complete!
TermDefinition
🔒
Pro Content
Subscribe to access all 69 OCR H446 A Level lessons.
£7.99/month
or £59/year
Subscribe now →
← 2.3.1b Linear & Binary Search 2.3.1 Algorithms Next: 2.3.1d Graph Traversal →