Thanks for the very well written and detailed explanation! I think from your comment I finally see a clearer path to a better implementation. Based on my own experience, I will probably start by writing it in Go first (that is the language I can think in most naturally), and then try to reason about how to make an idiomatic C version afterward, which will be interesting since I have not really written C in about 15 years.

I hope some of my thoughts turn out to be useful! I was a bit reluctant to offer most of them for fear they might sound like an attack, especially the things that would involve large changes to what you've already written.

Golang, like Python and JS, is garbage-collected; in some cases this is helpful for focusing attention on the central semantics of the algorithms, but it does have the disadvantage that it makes reasoning about space behavior and runtime performance much more difficult. One of Quicksort's chief benefits, for example, is that it's in-place, which the Python version in your "cheat sheet" isn't.