Description
The docs claim that select_nth_unstable is "O(n) worst-case", but the implementation exhibits O(n2) time complexity for some inputs. I'm not sure if this is a documentation error or an implementation error, but it's definitely one or the other.
The current implementation is a fairly normal Quickselect. Notably it only looks at a constant number of elements to determine a pivot, which cannot guarantee linear time complexity for quickselect. Median of medians must be used instead, which is different from the "median of medians" referenced in the code.
For actual proof that pathological cases exist, here's a playground link. It generates close to the worst possible input for a fixed length, and compares the time for that against the time for a random input. For a length of ~128k (the highest I can get the playground to go before it times out), the pathological input is around 1000 times slower than the random input.
Here's some graphs of runtime vs input length:
Both show runtime in seconds vs slice length, with blue being random inputs and red being pathological inputs. The second is a log-log graph with some lines fit to the data. The slopes on the log-log graph are roughly 1.3 and 2.3 for the blue and red lines respectively.
To uphold the linear worst-case guarantee, select_nth_unstable would need to use Median of medians. Introselect is the hybrid version, and Fast Deterministic Selection is the most recent work I'm aware of that looks at optimizing median of medians.
If the worst-case guarantee is relaxed to an average-case guarantee (that's all that C++ gives for nth_element), I think the docs should make it clear that the worst case is quadratic.