why do std::sort and partial_sort require random-a

2019-06-15 13:05发布

问题:

I was wondering why does the c++ standard require that std::sort should only take random-access iterators? I don't see the advantage, since both std::sort and std::list::sort have a complexity of N*log(N). Restricting std::sort to random-access iterators (RAI) seems to have made it necessary to write a separate function for lists with the same complexity.

The same applies to partial_sort, where the non-RAI counter-part for list is simply missing to this day.

Is this design because people used variants of quick_sort to implement std::sort historically?

If there is advantage for writing sort algorithms on RAI containers, would it better to make std::sort more general, and let RAI containers like std::vector provide specialized v.sort?

回答1:

O(N*log(N)) complexity doesn't imply that the container is iterated in order, nor that the changes to it are only made in scan order. To use sequential iterators would come at a O(N) memory cost to store all of those iterators.



回答2:

Algorithm complexity doesn't say it all. Actually in C++ (from a formal point of view) it doesn't say anything because you cannot grow N to infinity (size_t isn't an arbitrary precision number) thus every sort algorithm written in C++ is (formally) also O(1).

From a practical point of view std::sort is the grandson of qsort and it's implemented most probably as a variation of quicksort.

Using merge sort for arrays would require an extra storage proportional to the size of the array (the link to next element) while merge sort for lists doesn't require any extra space because you can reuse the link already present in the node (that it's going to be destroyed by sorting anyway).

The idea of programming without knowing what kind of container you're dealing with is mostly an illusion, thus having two different explicit ways to sort efficiently two different types of containers is not considered bad per se.

It's indeed annoying that std::sort doesn't contain a specialization also for list iterators (I'm not a template metaprogramming guru but it would seem quite straightforward to do).