Sorting and Related Functions¶
Julia has an extensive, flexible API for sorting and interacting with already-sorted arrays of values. By default, Julia picks reasonable algorithms and sorts in standard ascending order:
julia>sort([2,3,1])3-elementArray{Int64,1}:123You can easily sort in reverse order as well:
julia>sort([2,3,1],rev=true)3-elementArray{Int64,1}:321To sort an array in-place, use the “bang” version of the sort function:
julia>a=[2,3,1];julia>sort!(a);julia>a3-elementArray{Int64,1}:123Instead of directly sorting an array, you can compute a permutation of the array’s indices that puts the array into sorted order:
julia>v=randn(5)5-elementArray{Float64,1}:0.2972880.382396-0.597634-0.0104452-0.839027julia>p=sortperm(v)5-elementArray{Int64,1}:53412julia>v[p]5-elementArray{Float64,1}:-0.839027-0.597634-0.01044520.2972880.382396Arrays can easily be sorted according to an arbitrary transformation of their values:
julia>sort(v,by=abs)5-elementArray{Float64,1}:-0.01044520.2972880.382396-0.597634-0.839027Or in reverse order by a transformation:
julia>sort(v,by=abs,rev=true)5-elementArray{Float64,1}:-0.839027-0.5976340.3823960.297288-0.0104452If needed, the sorting algorithm can be chosen:
julia>sort(v,alg=InsertionSort)5-elementArray{Float64,1}:-0.839027-0.597634-0.01044520.2972880.382396All the sorting and order related functions rely on a “less than”
relation defining a total order on the values to be manipulated. The
isless function is invoked by default, but the relation can be
specified via the lt keyword.
Sorting Functions¶
sort!(v, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false])¶Sort the vector
vin place.QuickSortis used by default for numeric arrays whileMergeSortis used for other arrays. You can specify an algorithm to use via thealgkeyword (see Sorting Algorithms for available algorithms). Thebykeyword lets you provide a function that will be applied to each element before comparison; theltkeyword allows providing a custom “less than” function; userev=trueto reverse the sorting order. These options are independent and can be used together in all possible combinations: if bothbyandltare specified, theltfunction is applied to the result of thebyfunction;rev=truereverses whatever ordering specified via thebyandltkeywords.
sort(v, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false])¶Variant of
sort!that returns a sorted copy ofvleavingvitself unmodified.
sort(A, dim, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false])Sort a multidimensional array
Aalong the given dimension.
sortperm(v, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false])¶Return a permutation vector of indices of
vthat puts it in sorted order. Specifyalgto choose a particular sorting algorithm (see Sorting Algorithms).MergeSortis used by default, and since it is stable, the resulting permutation will be the lexicographically first one that puts the input array into sorted order – i.e. indices of equal elements appear in ascending order. If you choose a non-stable sorting algorithm such asQuickSort, a different permutation that puts the array into order may be returned. The order is specified using the same keywords assort!.See also
sortperm!()
sortperm!(ix, v, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false,] [initialized=false])¶Like
sortperm, but accepts a preallocated index vectorix. Ifinitializedisfalse(the default), ix is initialized to contain the values1:length(v).See also
sortperm()
sortrows(A, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false])¶Sort the rows of matrix
Alexicographically.
sortcols(A, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false])¶Sort the columns of matrix
Alexicographically.
Order-Related Functions¶
issorted(v, [by=<transform>,] [lt=<comparison>,] [rev=false])¶Test whether a vector is in sorted order. The
by,ltandrevkeywords modify what order is considered to be sorted just as they do forsort.
searchsorted(a, x, [by=<transform>,] [lt=<comparison>,] [rev=false])¶Returns the range of indices of
awhich compare as equal toxaccording to the order specified by theby,ltandrevkeywords, assuming thatais already sorted in that order. Returns an empty range located at the insertion point ifadoes not contain values equal tox.
searchsortedfirst(a, x, [by=<transform>,] [lt=<comparison>,] [rev=false])¶Returns the index of the first value in
agreater than or equal tox, according to the specified order. Returnslength(a)+1ifxis greater than all values ina.
searchsortedlast(a, x, [by=<transform>,] [lt=<comparison>,] [rev=false])¶Returns the index of the last value in
aless than or equal tox, according to the specified order. Returns0ifxis less than all values ina.
select!(v, k, [by=<transform>,] [lt=<comparison>,] [rev=false])¶Partially sort the vector
vin place, according to the order specified byby,ltandrevso that the value at indexk(or range of adjacent values ifkis a range) occurs at the position where it would appear if the array were fully sorted via a non-stable algorithm. Ifkis a single index, that value is returned; ifkis a range, an array of values at those indices is returned. Note thatselect!does not fully sort the input array.
select(v, k, [by=<transform>,] [lt=<comparison>,] [rev=false])¶Variant of
select!which copiesvbefore partially sorting it, thereby returning the same thing asselect!but leavingvunmodified.
selectperm(v, k, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false])¶Return a partial permutation of the vector
v, according to the order specified byby,ltandrev, so thatv[output]returns the firstk(or range of adjacent values ifkis a range) values of a fully sorted version ofv. Ifkis a single index (Integer), an array of the firstkindices is returned; ifkis a range, an array of those indices is returned. Note that the handling of integer values forkis different fromselectin that it returns a vector ofkelements instead of just thekth element. Also note that this is equivalent to, but more efficient than, callingsortperm(...)[k]
selectperm!(ix, v, k, [alg=<algorithm>,] [by=<transform>,] [lt=<comparison>,] [rev=false,] [initialized=false])¶Like
selectperm, but accepts a preallocated index vectorix. Ifinitializedisfalse(the default), ix is initialized to contain the values1:length(ix).
Sorting Algorithms¶
There are currently four sorting algorithms available in base Julia:
InsertionSortQuickSortPartialQuickSort(k)MergeSort
InsertionSort is an O(n^2) stable sorting algorithm. It is efficient
for very small n, and is used internally by QuickSort.
QuickSort is an O(n log n) sorting algorithm which is in-place,
very fast, but not stable – i.e. elements which are considered
equal will not remain in the same order in which they originally
appeared in the array to be sorted. QuickSort is the default
algorithm for numeric values, including integers and floats.
PartialQuickSort(k) is similar to QuickSort, but the output array
is only sorted up to index k if k is an integer, or in the range
of k if k is an OrdinalRange. For example:
x=rand(1:500,100)k=50k2=50:100s=sort(x;alg=QuickSort)ps=sort(x;alg=PartialQuickSort(k))qs=sort(x;alg=PartialQuickSort(k2))map(issorted,(s,ps,qs))# => (true, false, false)map(x->issorted(x[1:k]),(s,ps,qs))# => (true, true, false)map(x->issorted(x[k2]),(s,ps,qs))# => (true, false, true)s[1:k]==ps[1:k]# => trues[k2]==qs[k2]# => trueMergeSort is an O(n log n) stable sorting algorithm but is not
in-place – it requires a temporary array of half the size of the
input array – and is typically not quite as fast as QuickSort.
It is the default algorithm for non-numeric data.
The default sorting algorithms are chosen on the basis that they are
fast and stable, or appear to be so. For numeric types indeed,
QuickSort is selected as it is faster and indistinguishable in
this case from a stable sort (unless the array records its mutations
in some way). The stability property comes at a non-negligible cost,
so if you don’t need it, you may want to explicitly specify your
preferred algorithm, e.g. sort!(v,alg=QuickSort).
The mechanism by which Julia picks default sorting algorithms is
implemented via the Base.Sort.defalg function. It allows a
particular algorithm to be registered as the default in all sorting
functions for specific arrays. For example, here are the two default
methods from sort.jl:
defalg(v::AbstractArray)=MergeSortdefalg{T<:Number}(v::AbstractArray{T})=QuickSortAs for numeric arrays, choosing a non-stable default algorithm for array types for which the notion of a stable sort is meaningless (i.e. when two values comparing equal can not be distinguished) may make sense.