Code

dcsort.go — the skeleton

Create dcsort.go (see the panel). Four signatures, four contracts, four panics.

Three of the four are the same quicksort with a different pivot, so you write Partition once and use it three times.

What the test checks

  • MergeSort — stable, does not return the same slice (the input must be untouched), and stays under n·⌈log₂ n⌉ comparisons on every order;
  • QuickSortNaiveexactly n(n−1)/2 comparisons on sorted input. The test demands that precise number, because the failure is the lesson;
  • QuickSortMedian3 — far below quadratic on sorted input;
  • QuickSortRandom — fixed seed (rand.NewSource(1)), so the counts repeat.

One thing that is easy to miss

MergeSort returns a new slice rather than sorting in place, and the test checks that the input is left alone.

That is not fussiness — it is merge sort's price. It needs somewhere to merge into, and that somewhere is n extra elements. Quicksort needs none, and in step 7 you will see that this is why it is often faster despite making more comparisons.