Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between std::sort and std::stable_sort?

Tags:

c++

algorithm

I would like to know how std::sort and std::stable_sort differ with respect to functionality, memory and hardware? The documentation mentions that "Sorts the elements in the range [first,last) into ascending order, like sort, but stable_sort preserves the relative order of the elements with equivalent values.", but that didn't make sense to me. What is the "relative order" and "equivalent values"?

like image 806
user3603858 Avatar asked Jun 02 '14 00:06

user3603858


People also ask

What is the difference between sort and stable_sort?

Difference Between sort and stable_sort() Therefore, sort() may preserve the physical order of semantically equivalent values but can't be guaranteed. stable_sort() function usually uses mergesort. Therefore, stable_sort() preserve the physical order of semantically equivalent values and its guaranteed.

Is std::sort stable C++?

As of September 2020, it appears that libc++ std::sort happens to be stable for all ranges of size less than 31, and libstdc++ std::sort happens to be stable for all ranges of size less than 17. (Do not rely on this little factoid in production!)

What does std::sort do?

std::sort() is a built-in function in C++'s Standard Template Library. The function takes in a beginning iterator, an ending iterator, and (by default) sorts the iterable in ascending order. The function can also​ be used for custom sorting by passing in a comparator function that returns a boolean.

Why is std::sort faster than qsort?

In general, std::sort is indeed faster than qsort because of a couple of these things: qsort operates on void* , which first requires a dereference, and second requires the size of the data type to perform the swaps. Therefore, the swap operation of qsort is done every byte.


2 Answers

Yes, it's as you said, and this is not a concept unique to C++.

Stable sorts preserve the physical order of semantically equivalent values.


std::sort:

The order of equal elements is not guaranteed to be preserved.
Complexity: O(N·log(N)), where N = std::distance(first, last) comparisons

std::stable_sort:

The order of equal elements is guaranteed to be preserved.
Complexity: O(N·log^2(N)), where N = std::distance(first, last) applications of cmp. If additional memory is available, then the complexity is O(N·log(N)).

The implication is that std::stable_sort cannot be performed quite as efficiently in terms of execution time, unless "additional memory is available" in which case it is not being performed as efficiently in terms of memory consumption.

like image 100
Lightness Races in Orbit Avatar answered Oct 11 '22 19:10

Lightness Races in Orbit


As mentioned, the standard only notes that std::stable_sort preserves the original order for equal elements, while std::sort doesn't.

In the case of HP / Microsoft STL, std::sort is usually quick sort, unless the nesting gets too deep, in which case it switched to heap sort. Quick sort time complexity is typically O(n log(n)), but it's worst case is O(n^2), which is avoided with the switch to heap sort, since heap sort is always O(n log(n)) (but slower than quick sort so it's only used to avoid O(n^2)).

In the case of HP / Microsoft STL, std::stable_sort is a hybrid bottom up merge sort, using insertion sort to create sorted groups of 32 elements, then doing bottom up merge sort with the groups. The array (or vector) is split into two, a temporary array (or vector) 1/2 the size of the array to be sorted is allocated, and used to do a merge sort for both halfs of the array. Then one of the half arrays is moved to the temp array to do a final merge pass. Merge sort is also O(n log n), taking a bit longer for sorting arrays of objects, but merge sort is often faster if sorting an array of pointers to objects where a comparison function is included in the call. This because merge sort involves more moves but fewer compares than quick sort.

For sorting an array of integers, a radix sort is faster. If sorting by byte, then it takes 4 passes to sort an array of 32 bit integers, and 8 passes to sort an array of 64 bit integers.

like image 22
rcgldr Avatar answered Oct 11 '22 20:10

rcgldr