Cold & Serega
Serega Serega
I was just comparing merge sort to quicksort and got stuck on how to guarantee O(n log n) in the worst case without sacrificing readability.
Cold Cold
Use a pivot strategy that avoids the worst split – median‑of‑three or a random pivot – and add a depth guard that switches to heapsort when the recursion depth exceeds about 2·log₂n. That keeps the code compact, still reads like quicksort, and guarantees O(n log n) worst‑case.
Serega Serega
Sounds solid, just remember the median‑of‑three can still bite if your data is already partially sorted—maybe shuffle the array first, then pick the middle, and let the heapsort guard be the safety net. And hey, think of the recursion depth as a drum roll, you don’t want it to turn into a cacophony.
Cold Cold
You’re right, shuffling mitigates that risk, but it adds O(n) overhead. The depth guard is cheap, but you need to pick a tight threshold; 2·log₂n is a good start. Any other safeguards you’re considering?
Serega Serega
Yeah, add a quick check for already sorted runs – if the array is nearly sorted you can just skip to insertion sort on small chunks, it keeps the code clean. Also keep a small threshold for switching to insertion sort when sub‑arrays drop below, say, 20 elements; that keeps the recursion shallow and the constants low. Keep it modular, so each guard feels like its own tiny concerto, not a tangled symphony.
Cold Cold
Good idea. Verify the run check doesn’t cost more than the benefit. Keep the thresholds tight, and make sure the insertion switch triggers only when the remaining subarray is truly trivial. That way the guards stay efficient and the code stays readable.