Sorting and Related Functions
Julia tiene una API extensa y flexible para ordenar e interactuar con arreglos de valores ya ordenados. Por defecto, Julia elige algoritmos razonables y ordena en orden ascendente:
julia> sort([2,3,1])
3-element Vector{Int64}:
1
2
3
También puedes ordenar en orden inverso:
julia> sort([2,3,1], rev=true)
3-element Vector{Int64}:
3
2
1
sort
construye una copia ordenada dejando su entrada sin cambios. Usa la versión "bang" de la función de ordenamiento para mutar un array existente:
julia> a = [2,3,1];
julia> sort!(a);
julia> a
3-element Vector{Int64}:
1
2
3
En lugar de ordenar directamente un arreglo, puedes calcular una permutación de los índices del arreglo que coloca el arreglo en orden ordenado:
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
Los arreglos se pueden ordenar de acuerdo con una transformación arbitraria de sus valores:
julia> sort(v, by=abs)
5-element Array{Float64,1}:
-0.0104452
0.297288
0.382396
-0.597634
-0.839027
O en orden inverso por una transformación:
julia> sort(v, by=abs, rev=true)
5-element Array{Float64,1}:
-0.839027
-0.597634
0.382396
0.297288
-0.0104452
Si es necesario, se puede elegir el algoritmo de ordenamiento:
julia> sort(v, alg=InsertionSort)
5-element Array{Float64,1}:
-0.839027
-0.597634
-0.0104452
0.297288
0.382396
Todas las funciones relacionadas con la ordenación y el orden dependen de una relación de "menor que" que define un strict weak order sobre los valores a manipular. La función isless
se invoca por defecto, pero la relación se puede especificar a través de la palabra clave lt
, una función que toma dos elementos de un arreglo y devuelve true
si y solo si el primer argumento es "menor que" el segundo. Consulte sort!
y Alternate Orderings para más información.
Sorting Functions
Base.sort!
— Functionsort!(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)
Ordena el vector v
en su lugar. Se utiliza un algoritmo estable por defecto: se preserva el orden de los elementos que se comparan como iguales. Se puede seleccionar un algoritmo específico a través de la palabra clave alg
(ver Algoritmos de Ordenación para los algoritmos disponibles).
Los elementos se transforman primero con la función by
y luego se comparan de acuerdo con la función lt
o el orden order
. Finalmente, el orden resultante se invierte si rev=true
(esto preserva la estabilidad hacia adelante: los elementos que se comparan como iguales no se invierten). La implementación actual aplica la transformación by
antes de cada comparación en lugar de una vez por elemento.
No se permite pasar un lt
diferente de isless
junto con un order
diferente de Base.Order.Forward
o Base.Order.Reverse
; de lo contrario, todas las opciones son independientes y se pueden usar juntas en todas las combinaciones posibles. Tenga en cuenta que order
también puede incluir una transformación "by", en cuyo caso se aplica después de la definida con la palabra clave by
. Para más información sobre los valores de order
, consulte la documentación sobre Ordenamientos Alternativos.
Las relaciones entre dos elementos se definen de la siguiente manera (con "menor" y "mayor" intercambiados cuando rev=true
):
x
es menor quey
silt(by(x), by(y))
(oBase.Order.lt(order, by(x), by(y))
) devuelve verdadero.x
es mayor quey
siy
es menor quex
.x
ey
son equivalentes si ninguno es menor que el otro ("incomparable" a veces se usa como sinónimo de "equivalente").
El resultado de sort!
está ordenado en el sentido de que cada elemento es mayor o equivalente al anterior.
La función lt
debe definir un orden débil estricto, es decir, debe ser
- irreflexiva:
lt(x, x)
siempre devuelvefalse
, - asimétrica: si
lt(x, y)
devuelvetrue
, entonceslt(y, x)
devuelvefalse
, - transitiva:
lt(x, y) && lt(y, z)
implicalt(x, z)
, - transitiva en equivalencia:
!lt(x, y) && !lt(y, x)
y!lt(y, z) && !lt(z, y)
juntas implican!lt(x, z) && !lt(z, x)
. En palabras: six
ey
son equivalentes yy
yz
son equivalentes, entoncesx
yz
deben ser equivalentes.
Por ejemplo, <
es una función lt
válida para valores Int
, pero ≤
no lo es: viola la irreflexividad. Para valores Float64
, incluso <
es inválido ya que viola la cuarta condición: 1.0
y NaN
son equivalentes y también lo son NaN
y 2.0
, pero 1.0
y 2.0
no son equivalentes.
Véase también sort
, sortperm
, sortslices
, partialsort!
, partialsortperm
, issorted
, searchsorted
, insorted
, Base.Order.ord
.
Ejemplos
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)) # same as sort(0:3, by=abs(x->x-2))
4-element Vector{Int64}:
2
1
3
0
julia> sort([2, NaN, 1, NaN, 3]) # correct sort with default lt=isless
5-element Vector{Float64}:
1.0
2.0
3.0
NaN
NaN
julia> sort([2, NaN, 1, NaN, 3], lt=<) # wrong sort due to invalid lt. This behavior is undefined.
5-element Vector{Float64}:
2.0
NaN
1.0
NaN
3.0
sort!(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)
Ordena el arreglo multidimensional A
a lo largo de la dimensión dims
. Consulta la versión unidimensional de sort!
para una descripción de los posibles argumentos de palabra clave.
Para ordenar secciones de un arreglo, consulta sortslices
.
Esta función requiere al menos Julia 1.1.
Ejemplos
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
Base.sort
— Functionsort(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)
Variante de sort!
que devuelve una copia ordenada de v
dejando v
sin modificar.
Ejemplos
julia> v = [3, 1, 2];
julia> sort(v)
3-element Vector{Int64}:
1
2
3
julia> v
3-element Vector{Int64}:
3
1
2
sort(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)
Ordena un arreglo multidimensional A
a lo largo de la dimensión dada. Consulta sort!
para una descripción de los posibles argumentos de palabra clave.
Para ordenar secciones de un arreglo, consulta sortslices
.
Ejemplos
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
Base.sortperm
— Functionsortperm(A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])
Devuelve un vector o arreglo de permutación I
que coloca A[I]
en orden ascendente a lo largo de la dimensión dada. Si A
tiene más de una dimensión, entonces el argumento de palabra clave dims
debe ser especificado. El orden se especifica utilizando las mismas palabras clave que sort!
. La permutación está garantizada para ser estable incluso si el algoritmo de ordenamiento es inestable: los índices de elementos iguales aparecerán en orden ascendente.
Véase también sortperm!
, partialsortperm
, invperm
, indexin
. Para ordenar secciones de un arreglo, consulte sortslices
.
El método que acepta dims
requiere al menos Julia 1.9.
Ejemplos
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
Base.Sort.InsertionSort
— ConstantOrdenamientoPorInserción
Utiliza el algoritmo de ordenamiento por inserción.
El ordenamiento por inserción recorre la colección un elemento a la vez, insertando cada elemento en su posición correcta y ordenada en el vector de salida.
Características:
- estable: preserva el orden de los elementos que son iguales en comparación
(por ejemplo, "a" y "A" en un ordenamiento de letras que ignora mayúsculas).
- en el lugar en la memoria.
- rendimiento cuadrático en el número de elementos a ordenar:
es adecuado para colecciones pequeñas, pero no debe usarse para colecciones grandes.
Base.Sort.MergeSort
— ConstantMergeSort
Indique que una función de ordenamiento debe utilizar el algoritmo de ordenamiento por mezcla. El ordenamiento por mezcla divide la colección en subcolecciones y las fusiona repetidamente, ordenando cada subcolección en cada paso, hasta que toda la colección se ha recombinado en forma ordenada.
Características:
- estable: preserva el orden de los elementos que se comparan como iguales (por ejemplo, "a" y "A" en un ordenamiento de letras que ignora mayúsculas).
- no en su lugar en memoria.
- estrategia de dividir y conquistar.
- buen rendimiento para colecciones grandes, pero típicamente no tan rápido como
QuickSort
.
Base.Sort.QuickSort
— ConstantQuickSort
Indique que una función de ordenamiento debe utilizar el algoritmo de ordenamiento rápido, que no es estable.
Características:
- no estable: no preserva el orden de los elementos que comparan como iguales (por ejemplo, "a" y "A" en un ordenamiento de letras que ignora mayúsculas).
- en el lugar en memoria.
- divide y vencerás: estrategia de ordenamiento similar a
MergeSort
. - buen rendimiento para colecciones grandes.
Base.Sort.PartialQuickSort
— TypePartialQuickSort{T <: Union{Integer,OrdinalRange}}
Indica que una función de ordenamiento debe utilizar el algoritmo de ordenamiento rápido parcial. PartialQuickSort(k)
es como QuickSort
, pero solo se requiere encontrar y ordenar los elementos que terminarían en v[k]
si v
estuviera completamente ordenado.
Características:
- no estable: no preserva el orden de los elementos que comparan como iguales (por ejemplo, "a" y "A" en un ordenamiento de letras que ignora mayúsculas y minúsculas).
- en el lugar en memoria.
- divide y vencerás: estrategia de ordenamiento similar a
MergeSort
.
Ten en cuenta que PartialQuickSort(k)
no necesariamente ordena todo el arreglo. Por ejemplo,
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
Base.Sort.sortperm!
— Functionsortperm!(ix, A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])
Al igual que sortperm
, pero acepta un vector o arreglo de índices preasignado ix
con los mismos axes
que A
. ix
se inicializa para contener los valores LinearIndices(A)
.
El comportamiento puede ser inesperado cuando cualquier argumento mutado comparte memoria con cualquier otro argumento.
El método que acepta dims
requiere al menos Julia 1.9.
Ejemplos
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
Base.sortslices
— Functionsortslices(A; dims, alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)
Ordena las secciones de un arreglo A
. El argumento clave requerido dims
debe ser un entero o una tupla de enteros. Especifica la(s) dimensión(es) sobre las que se ordenan las secciones.
Por ejemplo, si A
es una matriz, dims=1
ordenará las filas, dims=2
ordenará las columnas. Ten en cuenta que la función de comparación predeterminada en secciones unidimensionales ordena lexicográficamente.
Para los demás argumentos clave, consulta la documentación de sort!
.
Ejemplos
julia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1) # Ordenar filas
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) # Ordenar columnas
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
Dimensiones superiores
sortslices
se extiende naturalmente a dimensiones superiores. Por ejemplo, si A
es un arreglo de 2x2x2, sortslices(A, dims=3)
ordenará las secciones dentro de la 3ª dimensión, pasando las secciones de 2x2 A[:, :, 1]
y A[:, :, 2]
a la función de comparación. Ten en cuenta que, aunque no hay un orden predeterminado en secciones de dimensiones superiores, puedes usar el argumento clave by
o lt
para especificar dicho orden.
Si dims
es una tupla, el orden de las dimensiones en dims
es relevante y especifica el orden lineal de las secciones. Por ejemplo, si A
es tridimensional y dims
es (1, 2)
, los ordenamientos de las dos primeras dimensiones se reorganizan de tal manera que las secciones (de la tercera dimensión restante) se ordenan. Si dims
es (2, 1)
en su lugar, se tomarán las mismas secciones, pero el orden del resultado será en orden por filas.
Ejemplos de dimensiones superiores
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
Order-Related Functions
Base.issorted
— Functionissorted(v, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)
Prueba si una colección está en orden clasificado. Las palabras clave modifican qué orden se considera clasificado, como se describe en la documentación de sort!
.
Ejemplos
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
Base.Sort.searchsorted
— Functionsearchsorted(v, x; by=identity, lt=isless, rev=false)
Devuelve el rango de índices en v
donde los valores son equivalentes a x
, o un rango vacío ubicado en el punto de inserción si v
no contiene valores equivalentes a x
. El vector v
debe estar ordenado de acuerdo con el orden definido por las palabras clave. Consulta sort!
para el significado de las palabras clave y la definición de equivalencia. Ten en cuenta que la función by
se aplica al valor buscado x
así como a los valores en v
.
El rango se encuentra generalmente utilizando búsqueda binaria, pero hay implementaciones optimizadas para algunas entradas.
Consulta también: searchsortedfirst
, sort!
, insorted
, findall
.
Ejemplos
julia> searchsorted([1, 2, 4, 5, 5, 7], 4) # coincidencia única
3:3
julia> searchsorted([1, 2, 4, 5, 5, 7], 5) # coincidencias múltiples
4:5
julia> searchsorted([1, 2, 4, 5, 5, 7], 3) # sin coincidencia, insertar en el medio
3:2
julia> searchsorted([1, 2, 4, 5, 5, 7], 9) # sin coincidencia, insertar al final
7:6
julia> searchsorted([1, 2, 4, 5, 5, 7], 0) # sin coincidencia, insertar al inicio
1:0
julia> searchsorted([1=>"one", 2=>"two", 2=>"two", 4=>"four"], 2=>"two", by=first) # comparar las claves de los pares
2:3
Base.Sort.searchsortedfirst
— Functionsearchsortedfirst(v, x; by=identity, lt=isless, rev=false)
Devuelve el índice del primer valor en v
que no está ordenado antes de x
. Si todos los valores en v
están ordenados antes de x
, devuelve lastindex(v) + 1
.
El vector v
debe estar ordenado de acuerdo con el orden definido por las palabras clave. Insertar x
en el índice devuelto mantendrá el orden ordenado. Consulta sort!
para el significado y uso de las palabras clave. Ten en cuenta que la función by
se aplica al valor buscado x
así como a los valores en v
.
El índice se encuentra generalmente utilizando búsqueda binaria, pero hay implementaciones optimizadas para algunas entradas.
Consulta también: searchsortedlast
, searchsorted
, findfirst
.
Ejemplos
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 4) # coincidencia única
3
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 5) # múltiples coincidencias
4
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 3) # sin coincidencia, insertar en el medio
3
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 9) # sin coincidencia, insertar al final
7
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 0) # sin coincidencia, insertar al inicio
1
julia> searchsortedfirst([1=>"one", 2=>"two", 4=>"four"], 3=>"three", by=first) # comparar las claves de los pares
3
Base.Sort.searchsortedlast
— Functionsearchsortedlast(v, x; by=identity, lt=isless, rev=false)
Devuelve el índice del último valor en v
que no está ordenado después de x
. Si todos los valores en v
están ordenados después de x
, devuelve firstindex(v) - 1
.
El vector v
debe estar ordenado de acuerdo con el orden definido por las palabras clave. Insertar x
inmediatamente después del índice devuelto mantendrá el orden ordenado. Consulta sort!
para el significado y uso de las palabras clave. Ten en cuenta que la función by
se aplica al valor buscado x
así como a los valores en v
.
El índice se encuentra generalmente utilizando búsqueda binaria, pero hay implementaciones optimizadas para algunas entradas.
Ejemplos
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 4) # coincidencia única
3
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 5) # múltiples coincidencias
5
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 3) # sin coincidencia, insertar en el medio
2
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 9) # sin coincidencia, insertar al final
6
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 0) # sin coincidencia, insertar al inicio
0
julia> searchsortedlast([1=>"one", 2=>"two", 4=>"four"], 3=>"three", by=first) # comparar las claves de los pares
2
Base.Sort.insorted
— Functioninsorted(x, v; by=identity, lt=isless, rev=false) -> Bool
Determina si un vector v
contiene algún valor equivalente a x
. El vector v
debe estar ordenado de acuerdo con el orden definido por las palabras clave. Consulta sort!
para el significado de las palabras clave y la definición de equivalencia. Ten en cuenta que la función by
se aplica al valor buscado x
así como a los valores en v
.
La verificación se realiza generalmente utilizando búsqueda binaria, pero hay implementaciones optimizadas para algunas entradas.
Consulta también in
.
Ejemplos
julia> insorted(4, [1, 2, 4, 5, 5, 7]) # coincidencia única
true
julia> insorted(5, [1, 2, 4, 5, 5, 7]) # coincidencias múltiples
true
julia> insorted(3, [1, 2, 4, 5, 5, 7]) # sin coincidencia
false
julia> insorted(9, [1, 2, 4, 5, 5, 7]) # sin coincidencia
false
julia> insorted(0, [1, 2, 4, 5, 5, 7]) # sin coincidencia
false
julia> insorted(2=>"TWO", [1=>"one", 2=>"two", 4=>"four"], by=first) # compara las claves de los pares
true
insorted
se agregó en Julia 1.6.
Base.Sort.partialsort!
— Functionpartialsort!(v, k; by=identity, lt=isless, rev=false)
Ordena parcialmente el vector v
en su lugar de modo que el valor en el índice k
(o rango de valores adyacentes si k
es un rango) ocurra en la posición donde aparecería si el arreglo estuviera completamente ordenado. Si k
es un índice único, ese valor se devuelve; si k
es un rango, se devuelve un arreglo de valores en esos índices. Ten en cuenta que partialsort!
puede no ordenar completamente el arreglo de entrada.
Para los argumentos de palabra clave, consulta la documentación de sort!
.
Ejemplos
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
Base.Sort.partialsort
— Functionpartialsort(v, k, by=identity, lt=isless, rev=false)
Variante de partialsort!
que copia v
antes de ordenarlo parcialmente, devolviendo así lo mismo que partialsort!
pero dejando v
sin modificar.
Base.Sort.partialsortperm
— Functionpartialsortperm(v, k; by=identity, lt=isless, rev=false)
Devuelve una permutación parcial I
del vector v
, de modo que v[I]
devuelve los valores de una versión completamente ordenada de v
en el índice k
. Si k
es un rango, se devuelve un vector de índices; si k
es un entero, se devuelve un único índice. El orden se especifica utilizando las mismas palabras clave que sort!
. La permutación es estable: los índices de elementos iguales aparecerán en orden ascendente.
Esta función es equivalente a, pero más eficiente que, llamar a sortperm(...)[k]
.
Ejemplos
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
Base.Sort.partialsortperm!
— Functionpartialsortperm!(ix, v, k; by=identity, lt=isless, rev=false)
Como partialsortperm
, pero acepta un vector de índices ix
preasignado del mismo tamaño que v
, que se utiliza para almacenar (una permutación de) los índices de v
.
ix
se inicializa para contener los índices de v
.
(Típicamente, los índices de v
serán 1:length(v)
, aunque si v
tiene un tipo de arreglo alternativo con índices que no comienzan en uno, como un OffsetArray
, ix
debe compartir esos mismos índices)
Al regresar, se garantiza que ix
tendrá los índices k
en sus posiciones ordenadas, de modo que
partialsortperm!(ix, v, k);
v[ix[k]] == partialsort(v, k)
El valor de retorno es el k
-ésimo elemento de ix
si k
es un entero, o una vista en ix
si k
es un rango.
El comportamiento puede ser inesperado cuando cualquier argumento mutado comparte memoria con cualquier otro argumento.
Ejemplos
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
Actualmente hay cuatro algoritmos de ordenamiento disponibles públicamente en Julia base:
Por defecto, la familia de funciones sort
utiliza algoritmos de ordenamiento estables que son rápidos en la mayoría de las entradas. La elección exacta del algoritmo es un detalle de implementación para permitir futuras mejoras en el rendimiento. Actualmente, se utiliza un híbrido de RadixSort
, ScratchQuickSort
, InsertionSort
y CountingSort
basado en el tipo de entrada, tamaño y composición. Los detalles de implementación están sujetos a cambios, pero actualmente están disponibles en la ayuda extendida de ??Base.DEFAULT_STABLE
y en las cadenas de documentación de los algoritmos de ordenamiento internos que se enumeran allí.
Puedes especificar explícitamente tu algoritmo preferido con la palabra clave alg
(por ejemplo, sort!(v, alg=PartialQuickSort(10:20))
) o reconfigurar el algoritmo de ordenamiento predeterminado para tipos personalizados añadiendo un método especializado a la función Base.Sort.defalg
. Por ejemplo, InlineStrings.jl define el siguiente método:
Base.Sort.defalg(::AbstractArray{<:Union{SmallInlineStrings, Missing}}) = InlineStringSort
El algoritmo de ordenamiento predeterminado (devuelto por Base.Sort.defalg
) está garantizado como estable desde Julia 1.9. Las versiones anteriores tenían casos extremos inestables al ordenar arreglos numéricos.
Alternate Orderings
Por defecto, sort
, searchsorted
y funciones relacionadas utilizan isless
para comparar dos elementos con el fin de determinar cuál debe ir primero. El tipo abstracto Base.Order.Ordering
proporciona un mecanismo para definir ordenamientos alternativos en el mismo conjunto de elementos: al llamar a una función de ordenamiento como sort!
, se puede proporcionar una instancia de Ordering
con el argumento de palabra clave order
.
Las instancias de Ordering
definen un orden a través de la función Base.Order.lt
, que funciona como una generalización de isless
. El comportamiento de esta función en Ordering
s personalizados debe satisfacer todas las condiciones de un strict weak order. Consulte sort!
para obtener detalles y ejemplos de funciones lt
válidas e inválidas.
Base.Order.Ordering
— TypeBase.Order.Ordering
Tipo abstracto que representa un orden débil estricto en un conjunto de elementos. Consulta sort!
para más información.
Utiliza Base.Order.lt
para comparar dos elementos de acuerdo con el orden.
Base.Order.lt
— Functionlt(o::Ordering, a, b) -> Bool
Prueba si a
es menor que b
de acuerdo con el orden o
.
Base.Order.ord
— Functionord(lt, by, rev::Union{Bool, Nothing}, order::Ordering=Forward)
Construye un objeto Ordering
a partir de los mismos argumentos utilizados por sort!
. Los elementos se transforman primero mediante la función by
(que puede ser identity
) y luego se comparan de acuerdo con la función lt
o un orden existente order
. lt
debe ser isless
o una función que obedezca las mismas reglas que el parámetro lt
de sort!
. Finalmente, el orden resultante se invierte si rev=true
.
No se permite pasar un lt
diferente de isless
junto con un order
diferente de Base.Order.Forward
o Base.Order.Reverse
; de lo contrario, todas las opciones son independientes y se pueden usar juntas en todas las combinaciones posibles.
Base.Order.Forward
— ConstantBase.Order.Forward
Orden predeterminado de acuerdo con isless
.
Base.Order.ReverseOrdering
— TypeReverseOrdering(fwd::Ordering=Forward)
Un envoltorio que invierte un orden.
Para un Ordering
dado o
, se cumple lo siguiente para todos a
, b
:
lt(ReverseOrdering(o), a, b) == lt(o, b, a)
Base.Order.Reverse
— ConstantBase.Order.Reverse
Orden inverso de acuerdo con isless
.
Base.Order.By
— TypeBy(by, order::Ordering=Forward)
Ordering
que aplica order
a los elementos después de que han sido transformados por la función by
.
Base.Order.Lt
— TypeLt(lt)
Ordering
que llama a lt(a, b)
para comparar elementos. lt
debe obedecer las mismas reglas que el parámetro lt
de sort!
.
Base.Order.Perm
— TypePerm(order::Ordering, data::AbstractVector)
Ordering
en los índices de data
donde i
es menor que j
si data[i]
es menor que data[j]
de acuerdo con order
. En el caso de que data[i]
y data[j]
sean iguales, i
y j
se comparan por valor numérico.