Function std.algorithm.sorting.sort
Sorts a random-access range according to the predicate less
. Performs
Ο(r.length * log(r.length)
) evaluations of less
. Stable sorting
requires hasAssignableElements!Range
to be true.
returns a std.range.SortedRange over the original range, which
functions that can take advantage of sorted data can then use to know that the
range is sorted and adjust accordingly. The std.range.SortedRange is a
wrapper around the original range, so both it and the original range are sorted,
but other functions won't know that the original range has been sorted, whereas
they can know that std.range.SortedRange has been sorted.
sort
The predicate is expected to satisfy certain rules in order for
to
behave as expected - otherwise, the program may fail on certain inputs (but not
others) when not compiled in release mode, due to the cursory sort
assumeSorted
check. Specifically,
expects sort
less(a,b) && less(b,c)
to imply
less(a,c)
(transitivity), and, conversely, !less(a,b) && !less(b,c)
to
imply !less(a,c)
. Note that the default predicate ("a < b"
) does not
always satisfy these conditions for floating point types, because the expression
will always be false
when either a
or b
is NaN.
Prototype
SortedRange!(Range,less) sort(alias less, std.algorithm.mutation.SwapStrategy ss, Range)( Range r ) if ((ss == SwapStrategy.unstable && (hasSwappableElements!Range || hasAssignableElements!Range) || ss != SwapStrategy.unstable && hasAssignableElements!Range) && isRandomAccessRange!Range && hasSlicing!Range && hasLength!Range);
Returns
The initial range wrapped as a SortedRange
with the predicate
binaryFun!less
.
Algorithms
is used for unstable sorting and
Timsort is used for stable sorting.
Each algorithm has benefits beyond stability. Introsort is generally faster but
Timsort may achieve greater speeds on data with low entropy or if predicate calls
are expensive. Introsort performs no allocations whereas Timsort will perform one
or more allocations per call. Both algorithms have Ο(n log n
) worst-case
time complexity.
See Also
std.range.assumeSorted
std.range.SortedRange
std.algorithm.mutation.SwapStrategy
std.functional.binaryFun
Example
int[] array = [ 1, 2, 3, 4 ]; // sort in descending order sort!("a > b")(array); assert(array == [ 4, 3, 2, 1 ]); // sort in ascending order sort(array); assert(array == [ 1, 2, 3, 4 ]); // sort with a delegate bool myComp(int x, int y) @safe pure nothrow { return x > y; } sort!(myComp)(array); assert(array == [ 4, 3, 2, 1 ]);
Example
// Showcase stable sorting string[] words = [ "aBc", "a", "abc", "b", "ABC", "c" ]; sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable)(words); assert(words == [ "a", "aBc", "abc", "ABC", "b", "c" ]);