De Wikipedia, la enciclopedia libre
Ir a navegaciónSaltar a buscar
Los pasos de Shellsort.
Intercambiar pares de elementos en pasos sucesivos de Shellsort con espacios 5, 3, 1

Shellsort , también conocido como clasificación de Shell o método de Shell , es una clasificación de comparación in situ . Se puede ver ya sea como una generalización de la clasificación por intercambio ( burbuja especie ) o clasificación por inserción ( tipo inserción ). [3] El método comienza clasificando pares de elementos muy separados entre sí, luego reduciendo progresivamente la brecha entre los elementos que se van a comparar. Al comenzar con elementos muy separados, puede mover algunos elementos fuera de lugar a su posición más rápido que un simple intercambio vecino más cercano. Donald Shell publicó la primera versión de este tipo en 1959. [4] [5]El tiempo de ejecución de Shellsort depende en gran medida de la secuencia de espacios que utiliza. Para muchas variantes prácticas, determinar su complejidad temporal sigue siendo un problema abierto .

Descripción

Shellsort es una optimización de la ordenación por inserción que permite el intercambio de elementos que están muy separados. La idea es organizar la lista de elementos de modo que, comenzando en cualquier lugar, tomando cada elemento h se produzca una lista ordenada. Dicha lista se dice que es h -sorted. También se puede considerar como h listas intercaladas, cada una clasificada individualmente. [6] Comenzar con valores grandes de h permite que los elementos se muevan largas distancias en la lista original, reduciendo rápidamente grandes cantidades de desorden y dejando menos trabajo para los pasos de h -sort más pequeños . [7] Si la lista está ordenada por k para un entero menor k, entonces la lista permanece ordenada por h . Siguiendo esta idea para una secuencia decreciente de valores h que terminan en 1, se garantiza que dejará una lista ordenada al final. [6]

En términos simplistas, esto significa que si tenemos una matriz de 1024 números, nuestro primer espacio ( h ) podría ser 512. Luego, recorremos la lista comparando cada elemento de la primera mitad con el elemento de la segunda mitad. Nuestro segundo espacio ( k ) es 256, que divide la matriz en cuatro secciones (comenzando en 0,256,512,768), y nos aseguramos de que los primeros elementos de cada sección estén ordenados entre sí, luego el segundo elemento de cada sección, y así sucesivamente. . En la práctica, la secuencia de espacios podría ser cualquier cosa, pero el último espacio es siempre 1 para finalizar la clasificación (terminando efectivamente con una clasificación de inserción ordinaria).

A continuación se muestra un ejemplo de ejecución de Shellsort con espacios 5, 3 y 1.

La primera pasada, clasificación 5, realiza la clasificación por inserción en cinco subarreglos separados ( a 1 , a 6 , a 11 ), ( a 2 , a 7 , a 12 ), ( a 3 , a 8 ), ( a 4 , a 9 ), ( un 5 , un 10 ). Por ejemplo, cambia el subarreglo ( un 1 , un 6 , un 11) de (62, 17, 25) a (17, 25, 62). La siguiente pasada, 3-sorting, realiza una ordenación por inserción en los tres subarreglos ( a 1 , a 4 , a 7 , a 10 ), ( a 2 , a 5 , a 8 , a 11 ), ( a 3 , a 6 , un 9 , un 12 ). El último paso, 1-sorting, es un tipo de inserción ordinario de toda la matriz ( a 1 , ..., a 12 ).

Como ilustra el ejemplo, los subarreglos en los que opera Shellsort son inicialmente cortos; después son más largos pero casi ordenados. En ambos casos, la clasificación por inserción funciona de manera eficiente.

Shellsort no es estable : puede cambiar el orden relativo de elementos con valores iguales. Es un algoritmo de clasificación adaptativo en el sentido de que se ejecuta más rápido cuando la entrada está parcialmente clasificada.

Pseudocódigo

Utilizando la secuencia de huecos de Marcin Ciura, con una ordenación de inserción interna.

# Ordene una matriz a [0 ... n-1]. huecos  =  [ 701 ,  301 ,  132 ,  57 ,  23 ,  10 ,  4 ,  1 ]# Comience con la mayor brecha y el trabajo a una distancia de 1 foreach  ( brecha  en  las lagunas ) {  # Hacer una inserción con huecos de clasificación para este tamaño de la separación.  # Los primeros elementos de espacio a [0..gap-1] ya están en orden de  espacio # sigue agregando un elemento más hasta que toda la matriz esté ordenada  por  espacios ( i  =  espacio ;  i  <  n ;  i  + =  1 )  {  # agregar a [i] a los elementos que han sido ordenados por espacios  # guardar un [i] en temp y hacer un agujero en la posición i  temp  =  a [ i ] # desplazar elementos anteriores ordenados por espacios hacia arriba hasta que se encuentre la ubicación correcta para un [i]  para  ( j  =  i ;  j  > =  espacio  y  a [ j  -  espacio ]  >  temp ;  j  - =  espacio )  {  a [ j ]  =  a [ j  -  gap ]  }  # poner temp (el original a [i]) en su ubicación correcta  a [ j ]  =  temp  } }

Secuencias de huecos

La cuestión de decidir qué secuencia de huecos utilizar es difícil. Cada secuencia de espacios que contiene 1 produce una clasificación correcta (ya que esto hace que la pasada final sea una clasificación de inserción ordinaria); sin embargo, las propiedades de las versiones de Shellsort así obtenidas pueden ser muy diferentes. Muy pocos huecos ralentizan los pases y demasiados huecos producen una sobrecarga.

La siguiente tabla compara la mayoría de las secuencias de huecos propuestas publicadas hasta ahora. Algunos de ellos tienen elementos decrecientes que dependen del tamaño de la matriz ordenada ( N ). Otros son sucesiones infinitas crecientes, cuyos elementos menores que N deben usarse en orden inverso.

Cuando la representación binaria de N contiene muchos ceros consecutivos, Shellsort utilizando la secuencia de espacios original de Shell hace comparaciones Θ ( N 2 ) en el peor de los casos. Por ejemplo, este caso ocurre para N igual a una potencia de dos cuando los elementos mayores y menores que la mediana ocupan posiciones pares e impares respectivamente, ya que se comparan solo en la última pasada.

Aunque tiene una mayor complejidad que el O ( N  log  N ) que es óptimo para tipos de comparación, la versión de Pratt se presta para clasificar redes y tiene la misma complejidad de puerta asintótica que el clasificador bitónico de Batcher .

Gonnet y Baeza-Yates observaron que Shellsort hace la menor cantidad de comparaciones en promedio cuando las proporciones de brechas sucesivas son aproximadamente iguales a 2.2. [13] Esta es la razón por la que su secuencia con razón 2.2 y la secuencia de Tokuda con razón 2.25 resultan eficientes. Sin embargo, no se sabe por qué es así. Sedgewick recomienda utilizar espacios que tengan divisores comunes máximos bajos o que sean coprimos por pares . [16] [ verificación fallida ]

Con respecto al número promedio de comparaciones, la secuencia de Ciura [15] tiene el mejor desempeño conocido; los espacios de 701 no se determinaron, pero la secuencia se puede extender aún más de acuerdo con la fórmula recursiva.

La secuencia de Tokuda, definida por la fórmula simple , donde , , se puede recomendar para aplicaciones prácticas.

Si el tamaño máximo de entrada es pequeño, como puede ocurrir si de Shell se utiliza en pequeñas submatrices por otro recursivo algoritmo de clasificación tales como quicksort o de combinación de tipo , entonces es posible para tabular una secuencia óptima para cada tamaño de entrada. [17]

Complejidad computacional

Se cumple la siguiente propiedad: después de h 2 -ordenar cualquier matriz h 1 -sorted, la matriz permanece h 1 -sorted. [18] Cada matriz h 1 clasificada y h 2 también está clasificada ( a 1 h 1 + a 2 h 2 ), para cualquier número entero no negativo a 1 y a 2 . Por lo tanto, la complejidad del peor caso de Shellsort está relacionada con el problema de Frobenius : para enteros dados h 1 , ..., h ncon gcd = 1, el número de Frobenius g ( h 1 , ..., h n ) es el número entero más grande que no puede ser representado como una 1 h 1 + ... + a n h n con entero no negativo un 1 , .. ., una n . Usando fórmulas conocidas para números de Frobenius, podemos determinar la complejidad del peor caso de Shellsort para varias clases de secuencias de espacios. [19] Los resultados probados se muestran en la tabla anterior.

Con respecto al número promedio de operaciones, ninguno de los resultados probados se refiere a una secuencia práctica de brechas. Para espacios que son potencias de dos, Espelid calculó este promedio como. [20] Knuth determinó que la complejidad promedio de clasificar una matriz de N elementos con dos espacios ( h , 1). [3] Se deduce que un Shellsort de dos pasadas con h = Θ ( N 1/3 ) hace en promedio O ( N 5/3 ) comparaciones / inversiones / tiempo de ejecución. Yao encontró la complejidad promedio de un Shellsort de tres pasadas. [21] Su resultado fue refinado por Janson y Knuth: [22] el número promedio de comparaciones / inversiones / tiempo de ejecución realizado durante un Shellsort con tres espacios ( ch , cg , 1), donde h y g son coprimos, es en la primera pasada, en el segundo pase y en el tercer pase. ψ ( h , g ) en la última fórmula es una función complicada asintóticamente igual a. En particular, cuando h = Θ ( N 7/15 ) y g = Θ ( N 1/5 ), el tiempo medio de clasificación es O ( N 23/15 ).

Con base en experimentos, se conjetura que Shellsort con la secuencia gap de Hibbard se ejecuta en un tiempo promedio de O ( N 5/4 ), [3] y que la secuencia de Gonnet y Baeza-Yates requiere en promedio 0.41 N  ln  N  (ln ln  N  + 1/6) el elemento se mueve. [13] Las aproximaciones del número medio de operaciones presentadas anteriormente para otras secuencias fallan cuando las matrices ordenadas contienen millones de elementos.

El siguiente gráfico muestra el número medio de comparaciones de elementos en varias variantes de Shellsort, dividido por el límite inferior teórico, es decir, log 2 N !, donde se ha ampliado la secuencia 1, 4, 10, 23, 57, 132, 301, 701 según la fórmula.

Número medio de comparaciones de clasificación de shell (inglés) .svg

Aplicando la teoría de la complejidad de Kolmogorov , Jiang, Li y Vitányi [23] demostraron el siguiente límite inferior para el orden del número promedio de operaciones / tiempo de ejecución en un Shellsort p -pass: Ω ( pN 1 + 1 / p ) cuando p  ≤ log 2 N y Ω ( pN ) cuando p  > log 2 N . Por lo tanto, Shellsort tiene perspectivas de ejecutarse en un tiempo promedio que crece asintóticamente como N log Nsolo cuando se utilizan secuencias de espacios cuyo número de espacios crece en proporción al logaritmo del tamaño de la matriz. Sin embargo, se desconoce si Shellsort puede alcanzar este orden asintótico de complejidad de casos promedio, que es óptimo para tipos de comparación. Vitányi [24] mejoró el límite inferior para cada número de pases. para donde . Este resultado implica, por ejemplo, el límite inferior de Jiang-Li-Vitányi para todos-pasa secuencias de incremento y mejora ese límite inferior para secuencias de incremento particulares. De hecho, todos los límites (inferior y superior) conocidos actualmente para el caso medio se corresponden con precisión con este límite inferior. Por ejemplo, esto da el nuevo resultado de que el límite superior de Janson-Knuth coincide con el límite inferior resultante para la secuencia de incremento utilizada, lo que muestra que Shellsort de tres pasadas para esta secuencia de incremento utilizacomparaciones / inversiones / tiempo de ejecución. La fórmula nos permite buscar secuencias de incrementos que produzcan límites inferiores desconocidos; por ejemplo, una secuencia de incremento para cuatro pasadas que tiene un límite inferior mayor que para la secuencia de incremento . El límite inferior se convierte en

La complejidad del peor de los casos de cualquier versión de Shellsort es de orden superior: Plaxton, Poonen y Suel demostraron que crece al menos tan rápido como. [25] [26]

Aplicaciones

Shellsort realiza más operaciones y tiene una mayor tasa de fallas de caché que Quicksort . Sin embargo, dado que se puede implementar usando poco código y no usa la pila de llamadas , algunas implementaciones de la función qsort en la biblioteca estándar de C dirigidas a sistemas embebidos la usan en lugar de quicksort. Shellsort se usa, por ejemplo, en la biblioteca uClibc . [27] Por razones similares, en el pasado, Shellsort se usaba en el kernel de Linux . [28]

Shellsort también puede servir como un sub-algoritmo de ordenamiento introspectivo , para ordenar subarreglos cortos y prevenir una desaceleración cuando la profundidad de recursividad excede un límite dado. Este principio se emplea, por ejemplo, en el compresor bzip2 . [29]

Ver también

  • Tipo de peine

Referencias

  1. ↑ a b c Pratt, Vaughan Ronald (1979). Shellsort y Sorting Networks (Disertaciones destacadas en Ciencias de la Computación) . Guirnalda. ISBN 978-0-8240-4406-0.
  2. ^ "Shellsort y comparaciones" .
  3. ↑ a b c d e Knuth, Donald E. (1997). "Método de Shell". El arte de la programación informática. Volumen 3: Clasificación y búsqueda (2ª ed.). Reading, Massachusetts: Addison-Wesley. págs. 83–95. ISBN 978-0-201-89685-5.
  4. ↑ a b Shell, DL (1959). "Un procedimiento de clasificación de alta velocidad" (PDF) . Comunicaciones de la ACM . 2 (7): 30–32. doi : 10.1145 / 368370.368387 .
  5. Algunos libros de texto y referencias más antiguos llaman a esto el tipo "Shell-Metzner" en honor a Marlene Metzner Norton , pero según Metzner, "no tuve nada que ver con el tipo, y mi nombre nunca debería haber estado asociado". Consulte "Clasificación de Shell" . Instituto Nacional de Estándares y Tecnología . Consultado el 17 de julio de 2007 .
  6. ↑ a b c Sedgewick, Robert (1998). Algoritmos en C . 1 (3ª ed.). Addison-Wesley. págs.  273-281 . ISBN 978-0-201-31452-6.
  7. ^ Kernighan, Brian W .; Ritchie, Dennis M. (1996). El lenguaje de programación C (2ª ed.). Prentice Hall. pag. 62. ISBN 978-7-302-02412-5.
  8. ^ Frank, RM; Lázaro, RB (1960). "Un procedimiento de clasificación de alta velocidad". Comunicaciones de la ACM . 3 (1): 20-22. doi : 10.1145 / 366947.366957 .
  9. ^ Hibbard, Thomas N. (1963). "Un estudio empírico de clasificación de almacenamiento mínimo". Comunicaciones de la ACM . 6 (5): 206–213. doi : 10.1145 / 366552.366557 .
  10. ^ Papernov, AA; Stasevich, GV (1965). "Un método de clasificación de información en memorias de computadora" (PDF) . Problemas de transmisión de información . 1 (3): 63–75.
  11. ^ Incerpi, Janet; Sedgewick, Robert (1985). "Límites superiores mejorados en Shellsort" (PDF) . Revista de Ciencias de la Computación y Sistemas . 31 (2): 210–224. doi : 10.1016 / 0022-0000 (85) 90042-x .
  12. ^ Sedgewick, Robert (1986). "Un nuevo límite superior para Shellsort". Revista de algoritmos . 7 (2): 159-173. doi : 10.1016 / 0196-6774 (86) 90001-5 .
  13. ^ a b c Gonnet, Gaston H .; Baeza-Yates, Ricardo (1991). "Shellsort". Manual de algoritmos y estructuras de datos: en Pascal y C (2ª ed.). Reading, Massachusetts: Addison-Wesley. págs. 161-163. ISBN 978-0-201-41607-7. Experimentos extensos indican que la secuencia definida por α = 0,45454 <5/11 funciona significativamente mejor que otras secuencias. La forma más fácil de calcular 0.45454 n es utilizando aritmética de números enteros.(5 * n — 1)/11
  14. ^ Tokuda, Naoyuki (1992). "Un Shellsort mejorado". En van Leeuven, Jan (ed.). Actas del 12º Congreso Mundial de Computación de IFIP sobre algoritmos, software y arquitectura . Amsterdam: North-Holland Publishing Co. págs. 449–457. ISBN 978-0-444-89747-3.
  15. ↑ a b Ciura, Marcin (2001). "Mejores incrementos para el caso medio de Shellsort" (PDF) . En Freiwalds, Rusins ​​(ed.). Actas del XIII Simposio Internacional sobre Fundamentos de la Teoría de la Computación . Londres: Springer-Verlag. págs. 106-117. ISBN  978-3-540-42487-1.
  16. ^ Sedgewick, Robert (1998). "Shellsort". Algoritmos en C ++, Partes 1–4: Fundamentos, Estructura de datos, Clasificación, Búsqueda . Reading, Massachusetts: Addison-Wesley. págs. 285-292. ISBN 978-0-201-35088-3.
  17. ^ Forshell, Olof (22 de mayo de 2018). "¿Cómo elegir las longitudes de mis subsecuencias para un tipo de caparazón?" . Desbordamiento de pila . ¿Comentarios adicionales en la secuencia de huecos más rápida para la clasificación de proyectiles? (23 de mayo de 2018).
  18. ^ Gale, David ; Karp, Richard M. (abril de 1972). "Un fenómeno en la teoría de la clasificación" (PDF) . Revista de Ciencias de la Computación y Sistemas . 6 (2): 103-115. doi : 10.1016 / S0022-0000 (72) 80016-3 .
  19. ^ Selmer, Ernst S. (marzo de 1989). "Sobre Shellsort y el problema de Frobenius" (PDF) . BIT Matemáticas numéricas . 29 (1): 37–40. doi : 10.1007 / BF01932703 . hdl : 1956/19572 .
  20. ^ Espelid, Terje O. (diciembre de 1973). "Análisis de un algoritmo Shellsort". BIT Matemáticas numéricas . 13 (4): 394–400. doi : 10.1007 / BF01933401 . El resultado citado es la ecuación (8) de la p. 399.
  21. ^ Yao, Andrew Chi-Chih (1980). "Un análisis de ( h , k , 1) -Shellsort" (PDF) . Revista de algoritmos . 1 (1): 14–50. doi : 10.1016 / 0196-6774 (80) 90003-6 . STAN-CS-79-726. Archivado desde el original (PDF) el 4 de marzo de 2019.
  22. ^ Janson, Svante ; Knuth, Donald E. (1997). "Shellsort con tres incrementos" (PDF) . Estructuras y algoritmos aleatorios . 10 (1-2): 125-142. arXiv : cs / 9608105 . CiteSeerX 10.1.1.54.9911 . doi : 10.1002 / (SICI) 1098-2418 (199701/03) 10: 1/2 <125 :: AID-RSA6> 3.0.CO; 2-X .  
  23. ^ Jiang, Tao; Li, Ming ; Vitányi, Paul (septiembre de 2000). "Un límite inferior en la complejidad de casos promedio de Shellsort" (PDF) . Revista de la ACM . 47 (5): 905–911. arXiv : cs / 9906008 . CiteSeerX 10.1.1.6.6508 . doi : 10.1145 / 355483.355488 .  
  24. ^ Vitányi, Paul (marzo de 2018). "En la complejidad de casos promedio de Shellsort" (PDF) . Estructuras y algoritmos aleatorios . 52 (2): 354–363. arXiv : 1501.06461 . doi : 10.1002 / rsa.20737 .
  25. ^ Plaxton, C. Greg; Poonen, Bjorn ; Suel, Torsten (24 a 27 de octubre de 1992). Límites inferiores mejorados para Shellsort (PDF) . Simposio anual sobre fundamentos de la informática (FOCS 1992) . 33 . Pittsburgh, Estados Unidos. págs. 226-235. CiteSeerX 10.1.1.43.1393 . doi : 10.1109 / SFCS.1992.267769 . ISBN   978-0-8186-2900-6.
  26. ^ Plaxton, C. Greg; Suel, Torsten (mayo de 1997). "Límites inferiores para Shellsort" (PDF) . Revista de algoritmos . 23 (2): 221–240. CiteSeerX 10.1.1.460.2429 . doi : 10.1006 / jagm.1996.0825 .  
  27. ^ Novoa, Manuel III. "libc / stdlib / stdlib.c" . Consultado el 29 de octubre de 2014 .
  28. ^ "núcleo / grupos.c" . Consultado el 5 de mayo de 2012 .
  29. ^ Julian Seward. "bzip2 / blocksort.c" . Consultado el 30 de marzo de 2011 .

Bibliografía

  • Knuth, Donald E. (1997). "Método de Shell". El arte de la programación informática. Volumen 3: Clasificación y búsqueda (2ª ed.). Reading, Massachusetts: Addison-Wesley. págs. 83–95. ISBN 978-0-201-89685-5.
  • Análisis de Shellsort y algoritmos relacionados , Robert Sedgewick, Cuarto Simposio Europeo de Algoritmos, Barcelona, ​​septiembre de 1996.

Enlaces externos

  • Algoritmos de clasificación animados: clasificación de Shell en la Wayback Machine (archivado el 10 de marzo de 2015) - demostración gráfica
  • Shellsort con espacios 5, 3, 1 como danza folclórica húngara