Sorting and Related Functions
Julia имеет обширный, гибкий API для сортировки и взаимодействия с уже отсортированными массивами значений. По умолчанию Julia выбирает разумные алгоритмы и сортирует в порядке возрастания:
julia> sort([2,3,1])
3-element Vector{Int64}:
1
2
3Вы также можете сортировать в обратном порядке:
julia> sort([2,3,1], rev=true)
3-element Vector{Int64}:
3
2
1sort создает отсортированную копию, оставляя его входные данные неизменными. Используйте "громкий" вариант функции сортировки, чтобы изменить существующий массив:
julia> a = [2,3,1];
julia> sort!(a);
julia> a
3-element Vector{Int64}:
1
2
3Вместо того чтобы напрямую сортировать массив, вы можете вычислить перестановку индексов массива, которая приведет массив в отсортированный порядок:
julia> v = randn(5)
5-element Array{Float64,1}:
0.297288
0.382396
-0.597634
-0.0104452
-0.839027
julia> p = sortperm(v)
5-element Array{Int64,1}:
5
3
4
1
2
julia> v[p]
5-element Array{Float64,1}:
-0.839027
-0.597634
-0.0104452
0.297288
0.382396Массивы могут быть отсортированы в соответствии с произвольной трансформацией их значений:
julia> sort(v, by=abs)
5-element Array{Float64,1}:
-0.0104452
0.297288
0.382396
-0.597634
-0.839027Или в обратном порядке с помощью преобразования:
julia> sort(v, by=abs, rev=true)
5-element Array{Float64,1}:
-0.839027
-0.597634
0.382396
0.297288
-0.0104452Если необходимо, можно выбрать алгоритм сортировки:
julia> sort(v, alg=InsertionSort)
5-element Array{Float64,1}:
-0.839027
-0.597634
-0.0104452
0.297288
0.382396Все функции, связанные с сортировкой и порядком, полагаются на отношение "меньше чем", определяющее strict weak order для значений, которые необходимо обработать. Функция isless вызывается по умолчанию, но отношение может быть указано через ключевое слово lt, функцию, которая принимает два элемента массива и возвращает true, если и только если первый аргумент "меньше чем" второй. См. sort! и Alternate Orderings для получения дополнительной информации.
Sorting Functions
Base.sort! — Functionsort!(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)Сортирует вектор v на месте. По умолчанию используется стабильный алгоритм: порядок элементов, которые сравниваются как равные, сохраняется. Конкретный алгоритм можно выбрать с помощью ключевого слова alg (см. Алгоритмы сортировки для доступных алгоритмов).
Элементы сначала преобразуются с помощью функции by, а затем сравниваются либо по функции lt, либо по порядку order. Наконец, полученный порядок инвертируется, если rev=true (это сохраняет стабильность впереди: элементы, которые сравниваются как равные, не инвертируются). Текущая реализация применяет преобразование by перед каждым сравнением, а не один раз для каждого элемента.
Передача lt, отличного от isless, вместе с order, отличным от Base.Order.Forward или Base.Order.Reverse, не допускается, в противном случае все параметры независимы и могут использоваться вместе во всех возможных комбинациях. Обратите внимание, что order также может включать преобразование "by", в этом случае оно применяется после того, что определено с помощью ключевого слова by. Для получения дополнительной информации о значениях order смотрите документацию по Альтернативным порядкам.
Отношения между двумя элементами определяются следующим образом (с "меньше" и "больше", обмененными, когда rev=true):
xменьшеy, еслиlt(by(x), by(y))(илиBase.Order.lt(order, by(x), by(y))) возвращает true.xбольшеy, еслиyменьшеx.xиyэквивалентны, если ни один из них не меньше другого (иногда используется "несравнимый" как синоним "эквивалентный").
Результат sort! отсортирован в том смысле, что каждый элемент больше или эквивалентен предыдущему.
Функция lt должна определять строгий слабый порядок, то есть она должна быть
- иррефлексивной:
lt(x, x)всегда возвращаетfalse, - асимметричной: если
lt(x, y)возвращаетtrue, тоlt(y, x)возвращаетfalse, - транзитивной:
lt(x, y) && lt(y, z)подразумеваетlt(x, z), - транзитивной в эквивалентности:
!lt(x, y) && !lt(y, x)и!lt(y, z) && !lt(z, y)вместе подразумевают!lt(x, z) && !lt(z, x). Другими словами: еслиxиyэквивалентны, иyиzэквивалентны, тоxиzдолжны быть эквивалентны.
Например, < является допустимой функцией lt для значений Int, но ≤ не является таковой: она нарушает иррефлексивность. Для значений Float64 даже < недопустим, так как нарушает четвертое условие: 1.0 и NaN эквивалентны, так же как NaN и 2.0, но 1.0 и 2.0 не эквивалентны.
Смотрите также sort, sortperm, sortslices, partialsort!, partialsortperm, issorted, searchsorted, insorted, Base.Order.ord.
Примеры
julia> v = [3, 1, 2]; sort!(v); v
3-element Vector{Int64}:
1
2
3
julia> v = [3, 1, 2]; sort!(v, rev = true); v
3-element Vector{Int64}:
3
2
1
julia> v = [(1, "c"), (3, "a"), (2, "b")]; sort!(v, by = x -> x[1]); v
3-element Vector{Tuple{Int64, String}}:
(1, "c")
(2, "b")
(3, "a")
julia> v = [(1, "c"), (3, "a"), (2, "b")]; sort!(v, by = x -> x[2]); v
3-element Vector{Tuple{Int64, String}}:
(3, "a")
(2, "b")
(1, "c")
julia> sort(0:3, by=x->x-2, order=Base.Order.By(abs)) # то же самое, что sort(0:3, by=abs(x->x-2))
4-element Vector{Int64}:
2
1
3
0
julia> sort([2, NaN, 1, NaN, 3]) # правильная сортировка с lt по умолчанию = isless
5-element Vector{Float64}:
1.0
2.0
3.0
NaN
NaN
julia> sort([2, NaN, 1, NaN, 3], lt=<) # неправильная сортировка из-за недопустимого lt. Это поведение неопределено.
5-element Vector{Float64}:
2.0
NaN
1.0
NaN
3.0sort!(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)Сортирует многомерный массив A вдоль размерности dims. См. однородную версию sort! для описания возможных аргументов ключевых слов.
Чтобы отсортировать срезы массива, обратитесь к sortslices.
Эта функция требует как минимум Julia 1.1.
Примеры
julia> A = [4 3; 1 2]
2×2 Matrix{Int64}:
4 3
1 2
julia> sort!(A, dims = 1); A
2×2 Matrix{Int64}:
1 2
4 3
julia> sort!(A, dims = 2); A
2×2 Matrix{Int64}:
1 2
3 4Base.sort — Functionsort(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)Вариант sort!, который возвращает отсортированную копию v, оставляя v без изменений.
Примеры
julia> v = [3, 1, 2];
julia> sort(v)
3-element Vector{Int64}:
1
2
3
julia> v
3-element Vector{Int64}:
3
1
2sort(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)Сортирует многомерный массив A вдоль заданного измерения. См. sort! для описания возможных аргументов ключевых слов.
Чтобы отсортировать срезы массива, обратитесь к sortslices.
Примеры
julia> A = [4 3; 1 2]
2×2 Matrix{Int64}:
4 3
1 2
julia> sort(A, dims = 1)
2×2 Matrix{Int64}:
1 2
4 3
julia> sort(A, dims = 2)
2×2 Matrix{Int64}:
3 4
1 2Base.sortperm — Functionsortperm(A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])Возвращает вектор или массив перестановки I, который упорядочивает A[I] в отсортированном порядке вдоль указанного измерения. Если A имеет более одно измерение, то аргумент ключевого слова dims должен быть указан. Порядок задается с использованием тех же ключевых слов, что и sort!. Перестановка гарантированно будет стабильной, даже если алгоритм сортировки нестабилен: индексы равных элементов будут появляться в порядке возрастания.
См. также sortperm!, partialsortperm, invperm, indexin. Чтобы отсортировать срезы массива, обратитесь к sortslices.
Метод, принимающий dims, требует как минимум Julia 1.9.
Примеры
julia> v = [3, 1, 2];
julia> p = sortperm(v)
3-element Vector{Int64}:
2
3
1
julia> v[p]
3-element Vector{Int64}:
1
2
3
julia> A = [8 7; 5 6]
2×2 Matrix{Int64}:
8 7
5 6
julia> sortperm(A, dims = 1)
2×2 Matrix{Int64}:
2 4
1 3
julia> sortperm(A, dims = 2)
2×2 Matrix{Int64}:
3 1
2 4Base.Sort.InsertionSort — ConstantСортировкаВставкамиИспользуйте алгоритм сортировки вставками.
Сортировка вставками проходит по коллекции по одному элементу за раз, вставляя каждый элемент на его правильное, отсортированное место в выходном векторе.
Характеристики:
- стабильная: сохраняет порядок элементов, которые сравниваются как равные
(например, "a" и "A" в сортировке букв, игнорирующей регистр).
- внутри памяти.
- квадратичная производительность по количеству элементов, которые нужно отсортировать:
она хорошо подходит для небольших коллекций, но не должна использоваться для больших.
Base.Sort.MergeSort — ConstantСортировкаСлияниемУкажите, что функция сортировки должна использовать алгоритм сортировки слиянием. Сортировка слиянием делит коллекцию на подсборки и многократно объединяет их, сортируя каждую подсборку на каждом этапе, пока вся коллекция не будет снова собрана в отсортированном виде.
Характеристики:
- стабильная: сохраняет порядок элементов, которые сравниваются как равные (например, "a" и "A" в сортировке букв, игнорирующей регистр).
- не на месте в памяти.
- стратегия разделяй и властвуй.
- хорошая производительность для больших коллекций, но обычно не так быстра, как
QuickSort.
Base.Sort.QuickSort — ConstantQuickSortУкажите, что функция сортировки должна использовать алгоритм быстрой сортировки, который не является стабильным.
Характеристики:
- не стабильный: не сохраняет порядок элементов, которые сравниваются как равные (например, "a" и "A" в сортировке букв, игнорирующей регистр).
- на месте в памяти.
- разделяй и властвуй: стратегия сортировки, аналогичная
MergeSort. - хорошая производительность для больших коллекций.
Base.Sort.PartialQuickSort — TypePartialQuickSort{T <: Union{Integer,OrdinalRange}}Укажите, что функция сортировки должна использовать алгоритм частичной быстрой сортировки. PartialQuickSort(k) похож на QuickSort, но требуется только найти и отсортировать элементы, которые окажутся в v[k], если v будет полностью отсортирован.
Характеристики:
- неустойчивая: не сохраняет порядок элементов, которые сравниваются как равные (например, "a" и "A" в сортировке букв, игнорирующей регистр).
- на месте в памяти.
- разделяй и властвуй: стратегия сортировки, аналогичная
MergeSort.
Обратите внимание, что PartialQuickSort(k) не обязательно сортирует весь массив. Например,
julia> x = rand(100);
julia> k = 50:100;
julia> s1 = sort(x; alg=QuickSort);
julia> s2 = sort(x; alg=PartialQuickSort(k));
julia> map(issorted, (s1, s2))
(true, false)
julia> map(x->issorted(x[k]), (s1, s2))
(true, true)
julia> s1[k] == s2[k]
trueBase.Sort.sortperm! — Functionsortperm!(ix, A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])Как и sortperm, но принимает предварительно выделенный вектор или массив индексов ix с такими же axes, как и A. ix инициализируется для содержимого значений LinearIndices(A).
Поведение может быть неожиданным, если какой-либо изменяемый аргумент разделяет память с любым другим аргументом.
Метод, принимающий dims, требует как минимум Julia 1.9.
Примеры
julia> v = [3, 1, 2]; p = zeros(Int, 3);
julia> sortperm!(p, v); p
3-element Vector{Int64}:
2
3
1
julia> v[p]
3-element Vector{Int64}:
1
2
3
julia> A = [8 7; 5 6]; p = zeros(Int,2, 2);
julia> sortperm!(p, A; dims=1); p
2×2 Matrix{Int64}:
2 4
1 3
julia> sortperm!(p, A; dims=2); p
2×2 Matrix{Int64}:
3 1
2 4Base.sortslices — Functionsortslices(A; dims, alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)Сортирует срезы массива A. Обязательный аргумент dims должен быть либо целым числом, либо кортежем целых чисел. Он указывает на размерность(и), по которой сортируются срезы.
Например, если A — это матрица, dims=1 отсортирует строки, dims=2 отсортирует столбцы. Обратите внимание, что функция сравнения по умолчанию для одномерных срезов сортирует лексикографически.
Для остальных аргументов по умолчанию смотрите документацию sort!.
Примеры
julia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1) # Сортировка строк
3×3 Matrix{Int64}:
-1 6 4
7 3 5
9 -2 8
julia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1, lt=(x,y)->isless(x[2],y[2]))
3×3 Matrix{Int64}:
9 -2 8
7 3 5
-1 6 4
julia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1, rev=true)
3×3 Matrix{Int64}:
9 -2 8
7 3 5
-1 6 4
julia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2) # Сортировка столбцов
3×3 Matrix{Int64}:
3 5 7
-1 -4 6
-2 8 9
julia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2, alg=InsertionSort, lt=(x,y)->isless(x[2],y[2]))
3×3 Matrix{Int64}:
5 3 7
-4 -1 6
8 -2 9
julia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2, rev=true)
3×3 Matrix{Int64}:
7 5 3
6 -4 -1
9 8 -2Более высокие размеры
sortslices естественно расширяется на более высокие размеры. Например, если A — это массив 2x2x2, sortslices(A, dims=3) отсортирует срезы в 3-й размерности, передавая 2x2 срезы A[:, :, 1] и A[:, :, 2] в функцию сравнения. Обратите внимание, что хотя для срезов более высоких размерностей нет порядка по умолчанию, вы можете использовать аргументы by или lt, чтобы указать такой порядок.
Если dims — это кортеж, порядок размерностей в dims имеет значение и указывает линейный порядок срезов. Например, если A трехмерный и dims равно (1, 2), порядок первых двух размерностей переставляется так, что срезы (оставшейся третьей размерности) сортируются. Если dims равно (2, 1), то будут взяты те же срезы, но порядок результата будет по строкам.
Примеры для более высоких размерностей
julia> A = [4 3; 2 1 ;;; 'A' 'B'; 'C' 'D']
2×2×2 Array{Any, 3}:
[:, :, 1] =
4 3
2 1
[:, :, 2] =
'A' 'B'
'C' 'D'
julia> sortslices(A, dims=(1,2))
2×2×2 Array{Any, 3}:
[:, :, 1] =
1 3
2 4
[:, :, 2] =
'D' 'B'
'C' 'A'
julia> sortslices(A, dims=(2,1))
2×2×2 Array{Any, 3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
'D' 'C'
'B' 'A'
julia> sortslices(reshape([5; 4; 3; 2; 1], (1,1,5)), dims=3, by=x->x[1,1])
1×1×5 Array{Int64, 3}:
[:, :, 1] =
1
[:, :, 2] =
2
[:, :, 3] =
3
[:, :, 4] =
4
[:, :, 5] =
5Order-Related Functions
Base.issorted — Functionissorted(v, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)Проверьте, отсортирована ли коллекция. Ключевые слова изменяют порядок, который считается отсортированным, как описано в документации sort!.
Примеры
julia> issorted([1, 2, 3])
true
julia> issorted([(1, "b"), (2, "a")], by = x -> x[1])
true
julia> issorted([(1, "b"), (2, "a")], by = x -> x[2])
false
julia> issorted([(1, "b"), (2, "a")], by = x -> x[2], rev=true)
true
julia> issorted([1, 2, -2, 3], by=abs)
trueBase.Sort.searchsorted — Functionsearchsorted(v, x; by=identity, lt=isless, rev=false)Возвращает диапазон индексов в v, где значения эквивалентны x, или пустой диапазон, расположенный в точке вставки, если v не содержит значений, эквивалентных x. Вектор v должен быть отсортирован в соответствии с порядком, определенным ключевыми словами. Смотрите sort! для понимания значений ключевых слов и определения эквивалентности. Обратите внимание, что функция by применяется как к искомому значению x, так и к значениям в v.
Диапазон обычно находится с использованием бинарного поиска, но существуют оптимизированные реализации для некоторых входных данных.
Смотрите также: searchsortedfirst, sort!, insorted, findall.
Примеры
julia> searchsorted([1, 2, 4, 5, 5, 7], 4) # одно совпадение
3:3
julia> searchsorted([1, 2, 4, 5, 5, 7], 5) # несколько совпадений
4:5
julia> searchsorted([1, 2, 4, 5, 5, 7], 3) # нет совпадений, вставка в середину
3:2
julia> searchsorted([1, 2, 4, 5, 5, 7], 9) # нет совпадений, вставка в конец
7:6
julia> searchsorted([1, 2, 4, 5, 5, 7], 0) # нет совпадений, вставка в начало
1:0
julia> searchsorted([1=>"one", 2=>"two", 2=>"two", 4=>"four"], 2=>"two", by=first) # сравнение ключей пар
2:3Base.Sort.searchsortedfirst — Functionsearchsortedfirst(v, x; by=identity, lt=isless, rev=false)Возвращает индекс первого значения в v, которое не упорядочено перед x. Если все значения в v упорядочены перед x, возвращает lastindex(v) + 1.
Вектор v должен быть отсортирован в соответствии с порядком, определенным ключевыми словами. Вставка x по возвращенному индексу сохранит отсортированный порядок. Обратитесь к sort! для понимания и использования ключевых слов. Обратите внимание, что функция by применяется как к искомому значению x, так и к значениям в v.
Индекс обычно находится с использованием бинарного поиска, но для некоторых входных данных существуют оптимизированные реализации.
Смотрите также: searchsortedlast, searchsorted, findfirst.
Примеры
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 4) # одно совпадение
3
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 5) # несколько совпадений
4
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 3) # нет совпадений, вставка посередине
3
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 9) # нет совпадений, вставка в конце
7
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 0) # нет совпадений, вставка в начале
1
julia> searchsortedfirst([1=>"one", 2=>"two", 4=>"four"], 3=>"three", by=first) # сравнение ключей пар
3Base.Sort.searchsortedlast — Functionsearchsortedlast(v, x; by=identity, lt=isless, rev=false)Возвращает индекс последнего значения в v, которое не расположено после x. Если все значения в v расположены после x, возвращает firstindex(v) - 1.
Вектор v должен быть отсортирован в соответствии с порядком, определенным ключевыми словами. Вставка x сразу после возвращенного индекса сохранит отсортированный порядок. Смотрите sort! для значения и использования ключевых слов. Обратите внимание, что функция by применяется как к искомому значению x, так и к значениям в v.
Индекс обычно находится с использованием бинарного поиска, но для некоторых входных данных существуют оптимизированные реализации.
Примеры
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 4) # одно совпадение
3
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 5) # несколько совпадений
5
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 3) # нет совпадений, вставка в середину
2
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 9) # нет совпадений, вставка в конец
6
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 0) # нет совпадений, вставка в начало
0
julia> searchsortedlast([1=>"one", 2=>"two", 4=>"four"], 3=>"three", by=first) # сравнение ключей пар
2Base.Sort.insorted — Functioninsorted(x, v; by=identity, lt=isless, rev=false) -> BoolОпределяет, содержит ли вектор v любое значение, эквивалентное x. Вектор v должен быть отсортирован в соответствии с порядком, определенным ключевыми словами. Смотрите sort! для понимания значений ключевых слов и определения эквивалентности. Обратите внимание, что функция by применяется как к искомому значению x, так и к значениям в v.
Проверка обычно выполняется с использованием бинарного поиска, но для некоторых входных данных существуют оптимизированные реализации.
Смотрите также in.
Примеры
julia> insorted(4, [1, 2, 4, 5, 5, 7]) # одно совпадение
true
julia> insorted(5, [1, 2, 4, 5, 5, 7]) # несколько совпадений
true
julia> insorted(3, [1, 2, 4, 5, 5, 7]) # нет совпадений
false
julia> insorted(9, [1, 2, 4, 5, 5, 7]) # нет совпадений
false
julia> insorted(0, [1, 2, 4, 5, 5, 7]) # нет совпадений
false
julia> insorted(2=>"TWO", [1=>"one", 2=>"two", 4=>"four"], by=first) # сравнить ключи пар
trueinsorted была добавлена в Julia 1.6.
Base.Sort.partialsort! — Functionpartialsort!(v, k; by=identity, lt=isless, rev=false)Частично отсортируйте вектор v на месте так, чтобы значение по индексу k (или диапазону смежных значений, если k является диапазоном) оказалось на позиции, где оно появилось бы, если массив был бы полностью отсортирован. Если k — это один индекс, то возвращается это значение; если k — это диапазон, возвращается массив значений по этим индексам. Обратите внимание, что partialsort! может не полностью отсортировать входной массив.
Для аргументов ключевых слов смотрите документацию sort!.
Примеры
julia> a = [1, 2, 4, 3, 4]
5-element Vector{Int64}:
1
2
4
3
4
julia> partialsort!(a, 4)
4
julia> a
5-element Vector{Int64}:
1
2
3
4
4
julia> a = [1, 2, 4, 3, 4]
5-element Vector{Int64}:
1
2
4
3
4
julia> partialsort!(a, 4, rev=true)
2
julia> a
5-element Vector{Int64}:
4
4
3
2
1Base.Sort.partialsort — Functionpartialsort(v, k, by=identity, lt=isless, rev=false)Вариант partialsort!, который копирует v перед частичной сортировкой, тем самым возвращая то же самое, что и partialsort!, но оставляя v неизменным.
Base.Sort.partialsortperm — Functionpartialsortperm(v, k; by=identity, lt=isless, rev=false)Возвращает частичную перестановку I вектора v, так что v[I] возвращает значения полностью отсортированной версии v по индексу k. Если k является диапазоном, возвращается вектор индексов; если k является целым числом, возвращается единственный индекс. Порядок задается с использованием тех же ключевых слов, что и sort!. Перестановка стабильна: индексы равных элементов будут появляться в порядке возрастания.
Эта функция эквивалентна, но более эффективна, чем вызов sortperm(...)[k].
Примеры
julia> v = [3, 1, 2, 1];
julia> v[partialsortperm(v, 1)]
1
julia> p = partialsortperm(v, 1:3)
3-element view(::Vector{Int64}, 1:3) with eltype Int64:
2
4
3
julia> v[p]
3-element Vector{Int64}:
1
1
2Base.Sort.partialsortperm! — Functionpartialsortperm!(ix, v, k; by=identity, lt=isless, rev=false)Как и partialsortperm, но принимает предвыделенный вектор индексов ix того же размера, что и v, который используется для хранения (перестановки) индексов v.
ix инициализируется так, чтобы содержать индексы v.
(Обычно индексы v будут 1:length(v), хотя если v имеет альтернативный тип массива с не единичными индексами, например, OffsetArray, ix должен использовать те же индексы)
По возвращении гарантируется, что ix будет содержать индексы k в их отсортированных позициях, так что
partialsortperm!(ix, v, k);
v[ix[k]] == partialsort(v, k)Возвращаемое значение — это k-й элемент ix, если k является целым числом, или представление ix, если k является диапазоном.
Поведение может быть неожиданным, когда любой измененный аргумент разделяет память с любым другим аргументом.
Примеры
julia> v = [3, 1, 2, 1];
julia> ix = Vector{Int}(undef, 4);
julia> partialsortperm!(ix, v, 1)
2
julia> ix = [1:4;];
julia> partialsortperm!(ix, v, 2:3)
2-element view(::Vector{Int64}, 2:3) with eltype Int64:
4
3```
Sorting Algorithms
В настоящее время в базовом Julia доступно четыре алгоритма сортировки:
По умолчанию семейство функций sort использует стабильные алгоритмы сортировки, которые быстро работают с большинством входных данных. Точный выбор алгоритма является деталью реализации, чтобы позволить будущие улучшения производительности. В настоящее время используется гибрид RadixSort, ScratchQuickSort, InsertionSort и CountingSort в зависимости от типа, размера и состава входных данных. Детали реализации могут изменяться, но в настоящее время доступны в расширенной помощи ??Base.DEFAULT_STABLE и в документации внутренних алгоритмов сортировки, перечисленных там.
Вы можете явно указать предпочитаемый алгоритм с помощью ключевого слова alg (например, sort!(v, alg=PartialQuickSort(10:20))) или перенастроить алгоритм сортировки по умолчанию для пользовательских типов, добавив специализированный метод в функцию Base.Sort.defalg. Например, InlineStrings.jl определяет следующий метод:
Base.Sort.defalg(::AbstractArray{<:Union{SmallInlineStrings, Missing}}) = InlineStringSortАлгоритм сортировки по умолчанию (возвращаемый Base.Sort.defalg) гарантированно является стабильным с версии Julia 1.9. Предыдущие версии имели нестабильные крайние случаи при сортировке числовых массивов.
Alternate Orderings
По умолчанию функции sort, searchsorted и связанные с ними функции используют isless для сравнения двух элементов с целью определения, какой из них должен идти первым. Абстрактный тип Base.Order.Ordering предоставляет механизм для определения альтернативных порядков для одного и того же набора элементов: при вызове функции сортировки, такой как sort!, экземпляр Ordering может быть предоставлен с аргументом ключевого слова order.
Экземпляры Ordering определяют порядок через функцию Base.Order.lt, которая работает как обобщение isless. Поведение этой функции для пользовательских Ordering должно удовлетворять всем условиям strict weak order. См. sort! для получения подробной информации и примеров допустимых и недопустимых функций lt.
Base.Order.Ordering — TypeBase.Order.OrderingАбстрактный тип, который представляет строгий слабый порядок на некотором множестве элементов. См. sort! для получения дополнительной информации.
Используйте Base.Order.lt, чтобы сравнить два элемента в соответствии с порядком.
Base.Order.lt — Functionlt(o::Ordering, a, b) -> BoolПроверьте, меньше ли a, чем b, согласно порядку o.
Base.Order.ord — Functionord(lt, by, rev::Union{Bool, Nothing}, order::Ordering=Forward)Создайте объект Ordering из тех же аргументов, которые используются в sort!. Элементы сначала преобразуются с помощью функции by (которая может быть identity), а затем сравниваются в соответствии с функцией lt или существующим порядком order. lt должен быть isless или функцией, которая подчиняется тем же правилам, что и параметр lt функции sort!. Наконец, полученный порядок будет перевернут, если rev=true.
Передача lt, отличного от isless, вместе с order, отличным от Base.Order.Forward или Base.Order.Reverse, не допускается, в противном случае все параметры независимы и могут использоваться вместе во всех возможных комбинациях.
Base.Order.Forward — ConstantBase.Order.ForwardСтандартный порядок согласно isless.
Base.Order.ReverseOrdering — TypeReverseOrdering(fwd::Ordering=Forward)Обертка, которая меняет порядок на обратный.
Для данного Ordering o выполняется следующее для всех a, b:
lt(ReverseOrdering(o), a, b) == lt(o, b, a)Base.Order.Reverse — ConstantBase.Order.ReverseОбратный порядок в соответствии с isless.
Base.Order.By — TypeBy(by, order::Ordering=Forward)Ordering, который применяет order к элементам после того, как они были преобразованы функцией by.
Base.Order.Lt — TypeLt(lt)Ordering, который вызывает lt(a, b) для сравнения элементов. lt должен подчиняться тем же правилам, что и параметр lt функции sort!.
Base.Order.Perm — TypePerm(order::Ordering, data::AbstractVector)Ordering по индексам data, где i меньше j, если data[i] меньше data[j] в соответствии с order. В случае, если data[i] и data[j] равны, i и j сравниваются по числовому значению.