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
?
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.
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).