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
 1

sort создает отсортированную копию, оставляя его входные данные неизменными. Используйте "громкий" вариант функции сортировки, чтобы изменить существующий массив:

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!Function
sort!(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.0
source
sort!(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 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  4
source
Base.sortFunction
sort(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
 2
source
sort(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  2
source
Base.sortpermFunction
sortperm(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.

Julia 1.9

Метод, принимающий 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  4
source
Base.Sort.InsertionSortConstant
СортировкаВставками

Используйте алгоритм сортировки вставками.

Сортировка вставками проходит по коллекции по одному элементу за раз, вставляя каждый элемент на его правильное, отсортированное место в выходном векторе.

Характеристики:

  • стабильная: сохраняет порядок элементов, которые сравниваются как равные

(например, "a" и "A" в сортировке букв, игнорирующей регистр).

  • внутри памяти.
  • квадратичная производительность по количеству элементов, которые нужно отсортировать:

она хорошо подходит для небольших коллекций, но не должна использоваться для больших.

source
Base.Sort.MergeSortConstant
СортировкаСлиянием

Укажите, что функция сортировки должна использовать алгоритм сортировки слиянием. Сортировка слиянием делит коллекцию на подсборки и многократно объединяет их, сортируя каждую подсборку на каждом этапе, пока вся коллекция не будет снова собрана в отсортированном виде.

Характеристики:

  • стабильная: сохраняет порядок элементов, которые сравниваются как равные (например, "a" и "A" в сортировке букв, игнорирующей регистр).
  • не на месте в памяти.
  • стратегия разделяй и властвуй.
  • хорошая производительность для больших коллекций, но обычно не так быстра, как QuickSort.
source
Base.Sort.QuickSortConstant
QuickSort

Укажите, что функция сортировки должна использовать алгоритм быстрой сортировки, который не является стабильным.

Характеристики:

  • не стабильный: не сохраняет порядок элементов, которые сравниваются как равные (например, "a" и "A" в сортировке букв, игнорирующей регистр).
  • на месте в памяти.
  • разделяй и властвуй: стратегия сортировки, аналогичная MergeSort.
  • хорошая производительность для больших коллекций.
source
Base.Sort.PartialQuickSortType
PartialQuickSort{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]
true
source
Base.Sort.sortperm!Function
sortperm!(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).

Warning

Поведение может быть неожиданным, если какой-либо изменяемый аргумент разделяет память с любым другим аргументом.

Julia 1.9

Метод, принимающий 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  4
source
Base.sortslicesFunction
sortslices(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] =
 5
source
Base.issortedFunction
issorted(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)
true
source
Base.Sort.searchsortedFunction
searchsorted(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:3
source
Base.Sort.searchsortedfirstFunction
searchsortedfirst(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) # сравнение ключей пар
3
source
Base.Sort.searchsortedlastFunction
searchsortedlast(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) # сравнение ключей пар
2
source
Base.Sort.insortedFunction
insorted(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) # сравнить ключи пар
true
Julia 1.6

insorted была добавлена в Julia 1.6.

source
Base.Sort.partialsort!Function
partialsort!(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
 1
source
Base.Sort.partialsortFunction
partialsort(v, k, by=identity, lt=isless, rev=false)

Вариант partialsort!, который копирует v перед частичной сортировкой, тем самым возвращая то же самое, что и partialsort!, но оставляя v неизменным.

source
Base.Sort.partialsortpermFunction
partialsortperm(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
 2
source
Base.Sort.partialsortperm!Function
partialsortperm!(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 является диапазоном.

Warning

Поведение может быть неожиданным, когда любой измененный аргумент разделяет память с любым другим аргументом.

Примеры

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

```

source

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
Julia 1.9

Алгоритм сортировки по умолчанию (возвращаемый 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.OrderingType
Base.Order.Ordering

Абстрактный тип, который представляет строгий слабый порядок на некотором множестве элементов. См. sort! для получения дополнительной информации.

Используйте Base.Order.lt, чтобы сравнить два элемента в соответствии с порядком.

source
Base.Order.ltFunction
lt(o::Ordering, a, b) -> Bool

Проверьте, меньше ли a, чем b, согласно порядку o.

source
Base.Order.ordFunction
ord(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, не допускается, в противном случае все параметры независимы и могут использоваться вместе во всех возможных комбинациях.

source
Base.Order.ReverseOrderingType
ReverseOrdering(fwd::Ordering=Forward)

Обертка, которая меняет порядок на обратный.

Для данного Ordering o выполняется следующее для всех a, b:

lt(ReverseOrdering(o), a, b) == lt(o, b, a)
source
Base.Order.ByType
By(by, order::Ordering=Forward)

Ordering, который применяет order к элементам после того, как они были преобразованы функцией by.

source
Base.Order.LtType
Lt(lt)

Ordering, который вызывает lt(a, b) для сравнения элементов. lt должен подчиняться тем же правилам, что и параметр lt функции sort!.

source
Base.Order.PermType
Perm(order::Ordering, data::AbstractVector)

Ordering по индексам data, где i меньше j, если data[i] меньше data[j] в соответствии с order. В случае, если data[i] и data[j] равны, i и j сравниваются по числовому значению.

source