Instrument sorting without changing its contract
Build a comparison harness for insertion sort, merge sort, and quicksort. Generate the same input once, copy it for each algorithm, and verify output before measuring performance.
fun isSorted(values: IntArray): Boolean =
(1 until values.size).all { values[it - 1] <= values[it] }
fun sameElements(before: IntArray, after: IntArray): Boolean =
before.sorted() == after.sorted()
These helpers separate ordering from permutation preservation. Count comparisons and writes in your own implementations to connect observations with complexity. Animation delays and logging must be excluded from performance measurements.
Acceptance checks
Use empty, singleton, sorted, reverse-sorted, all-equal, and seeded random inputs. For each result, check ordering and element preservation. For stability, use labeled records rather than integers alone.
Extension: visualize array state after each meaningful operation using an event list produced by the algorithm. Keep the renderer separate so the same implementation can run without UI overhead.
Check: report pivot policy, input distribution, copy costs, and recursion depth; one favorable random case does not demonstrate worst-case behavior.