6.2 Sorting Algorithms: Tracing, Comparisons, Correctness, and Efficiency

Key Takeaways

  • Selection sort always makes n(n − 1)/2 comparisons and at most n − 1 swaps; after pass k, the k smallest values are in their final positions.
  • Insertion sort makes only n − 1 comparisons on already-sorted data but n(n − 1)/2 on reverse-sorted data, so it is fast on nearly sorted lists.
  • After each bubble sort pass, the largest remaining value has moved to the end of the unsorted part; a swap flag lets the algorithm stop early when a pass makes no swaps.
  • Merge sort runs in O(n log n) in every case and is stable but needs O(n) extra memory; quicksort averages O(n log n) but degrades to O(n²) when pivots split the data badly.
  • A stable sort keeps records with equal keys in their original relative order, which matters when you sort by one field after another.
Last updated: September 2026

What this competency asks

ETS asks you to understand searching and sorting algorithms and to analyze sorting algorithms for correctness. The discussion questions ask you to describe common comparison-based sorts, such as insertion sort and selection sort, and to analyze the number of comparisons. ETS's sample question on this topic shows an unfamiliar sorting procedure and asks for the array after six iterations of its loop. The core skill is careful tracing, not memorized names.

Selection sort

On each pass, find the smallest value in the unsorted part and swap it into the first unsorted position.

void selectionSort ( int[ ] a, int n )
    for ( int i ← 0; i < n - 1; i ← i + 1 )
        int minIndex ← i
        for ( int j ← i + 1; j < n; j ← j + 1 )
            if ( a[j] < a[minIndex] )
                minIndex ← j
            end if
        end for
        swap ( a, i, minIndex )     // exchanges a[i] and a[minIndex]
    end for
end selectionSort

Trace on {29, 10, 14, 37, 13}:

After passSmallest foundArray
1 (i = 0)10 at index 1{10, 29, 14, 37, 13}
2 (i = 1)13 at index 4{10, 13, 14, 37, 29}
3 (i = 2)14 at index 2 (no change){10, 13, 14, 37, 29}
4 (i = 3)29 at index 4{10, 13, 14, 29, 37}

Comparisons: 4 + 3 + 2 + 1 = 10 = n(n − 1)/2 for n = 5. Selection sort always makes this many comparisons, even on sorted data. It does at most n − 1 swaps, which is useful when writing to memory is expensive.

Insertion sort

Keep a sorted prefix. Take the next value (the "key"), shift larger values in the prefix one place right, and insert the key into the gap.

void insertionSort ( int[ ] a, int n )
    for ( int i ← 1; i < n; i ← i + 1 )
        int key ← a[i]
        int j ← i - 1
        while ( ( j ≥ 0 ) and ( a[j] > key ) )
            a[j + 1] ← a[j]
            j ← j - 1
        end while
        a[j + 1] ← key
    end for
end insertionSort

Trace on {5, 2, 4, 6, 1}:

ikeyComparisons made (a[j] > key)Array after insertion
125 > 2{2, 5, 4, 6, 1}
245 > 4, 2 > 4 (false){2, 4, 5, 6, 1}
365 > 6 (false){2, 4, 5, 6, 1}
416 > 1, 5 > 1, 4 > 1, 2 > 1{1, 2, 4, 5, 6}

That is 1 + 2 + 1 + 4 = 8 value comparisons. On an already-sorted array, each key needs one comparison: n − 1 total, O(n). On a reverse-sorted array, it needs n(n − 1)/2. Insertion sort is the best simple choice for nearly sorted data.

The condition ( j ≥ 0 ) and ( a[j] > key ) relies on checking j ≥ 0 first, so the array is never indexed at −1. This is short-circuit evaluation (Section 7.4).

Bubble sort

Compare adjacent pairs and swap any that are out of order. Each pass carries the largest remaining value to the end.

One pass on {5, 1, 4, 2, 8}: swap 5 and 1 → {1, 5, 4, 2, 8}; swap 5 and 4 → {1, 4, 5, 2, 8}; swap 5 and 2 → {1, 4, 2, 5, 8}; 5 and 8 stay. After pass 1: {1, 4, 2, 5, 8}, and 8 is in its final place.

With a swapped flag, bubble sort stops after a pass with no swaps. That gives n − 1 comparisons, O(n), on sorted data. Its worst case is n(n − 1)/2 comparisons and as many swaps, O(n²).

Divide-and-conquer sorts

Merge sort splits the array in half, sorts each half recursively, and merges the two sorted halves in linear time. The array can be halved about log₂ n times, and each level of merging does O(n) work, so the total is O(n log n) in every case. It is stable (when merging equal values, it takes from the left half first), but it needs O(n) extra memory for merging.

Quicksort picks a pivot, partitions the array so smaller values come before the pivot and larger ones after, and then recursively sorts each side. Its average is O(n log n) and it sorts in place, apart from its recursion stack. If the pivot is always the smallest or largest value (for example, taking the first element as the pivot on data that is already sorted), each partition removes only one element and the time degrades to O(n²). A random pivot or a median-of-three choice makes that unlikely. Standard quicksort is not stable.

Stability

A sort is stable if records with equal keys keep their original relative order. Suppose a class list is already alphabetical and you sort it by grade level. A stable sort keeps each grade's students alphabetical. An unstable sort may not.

Summary table

AlgorithmBestAverageWorstExtra spaceStable?
Selection sortO(n²)O(n²)O(n²)O(1)No (standard version)
Insertion sortO(n)O(n²)O(n²)O(1)Yes
Bubble sort (with flag)O(n)O(n²)O(n²)O(1)Yes
Merge sortO(n log n)O(n log n)O(n log n)O(n)Yes
QuicksortO(n log n)O(n log n)O(n²)O(log n) average (recursion)No

Analyzing an unfamiliar sort for correctness

When a question shows a sorting procedure you have never seen:

  1. Trace a small input exactly as written, keeping a table of the array and the index variables after each loop iteration.
  2. Check the loop bounds. An inner loop that stops one element early leaves the last element unsorted. Using ≤ n indexes past the end.
  3. Check the comparison direction. < versus > decides ascending versus descending order.
  4. Test edge cases: an empty array, one element, duplicates, and already-sorted and reverse-sorted input.
  5. Count what the question asks for: passes, iterations of a specific loop, comparisons, or swaps. These are different quantities.
Test Your Knowledge

Selection sort (find the minimum of the unsorted part and swap it into place) is applied to {29, 10, 14, 37, 13}. What is the array after the first two passes?

A
B
C
D
Test Your Knowledge

How many comparisons does selection sort make on an array of 6 elements?

A
B
C
D
Test Your Knowledge

A list of employees is already sorted by hire date. It must now be sorted by department so that, within each department, employees stay in hire-date order. Which algorithm guarantees this?

A
B
C
D
Test Your Knowledge

A quicksort implementation always chooses the first element of the current subarray as the pivot. What is its running time on an array that is already sorted in ascending order?

A
B
C
D