Para la clasificación de propósito general, la respuesta parece ser no, como la ordenación rápida, la ordenación de fusión y la clasificación de acumulación tienden a tener un mejor rendimiento en los escenarios de peor y peor promedio. Sin embargo, la ordenación de inserción parece sobresalir en la ordenación incremental, es decir, agregar elementos a una lista de uno en uno durante un período prolongado mientras se mantiene ordenada la lista, especialmente si la clasificación de inserción se implementa como una lista vinculada (O (log) n) caso promedio vs. O (n)). Sin embargo, un montón parece ser capaz de realizar solo (o casi) también para la clasificación incremental (agregar o eliminar un único elemento de un montón tiene el peor escenario de O (log n)). Entonces, ¿qué ofrece exactamente la ordenación por inserción sobre otros algoritmos o montones de clasificación basados en comparación?¿Alguna vez hay una buena razón para usar Insertion Sort?
Respuesta
De http://www.sorting-algorithms.com/insertion-sort:
Aunque es uno de los algoritmos de clasificación elementales con O (n) tiempo peor de los casos, la inserción tipo es el algoritmo de elección ya sea cuando los datos es casi ordenado (porque es adaptativo) o cuando el tamaño del problema es pequeño (porque tiene una baja sobrecarga de ).
Por estas razones, y debido a que también es estable, la ordenación por inserción es utiliza a menudo como el caso base recursiva (cuando el tamaño del problema es pequeño) para mayores gastos generales de divide y vencerás algoritmos de clasificación, tales como fusionar ordenar o ordenar rápidamente.
Ah, me olvidé de la estabilidad ... Ninguno de los otros algoritmos que mencioné es estable. –
+1. El bucle interno de ordenación de inserción resulta ser una buena opción para CPU y cachés modernos: es un bucle muy ajustado que accede a la memoria solo en orden ascendente. –
Bueno, el quicksort se puede implementar como un tipo estable, pero dado que es óptimo para conjuntos aleatorios, creo que las funciones qsort eficientes aleatorizan los datos deliberadamente antes de la clasificación. – guns
La mayoría de los procedimientos de clasificación usarán quicksort y luego sorter de inserción para conjuntos de datos muy pequeños.
Un concepto importante en el análisis de algoritmos es análisis asintótico. En el caso de dos algoritmos con diferentes tiempos de ejecución asintóticos, como uno O (n^2) y un O (nlogn) como es el caso con ordenación de inserción y quicksort respectivamente, no es definitivo que uno sea más rápido que el otro .
La distinción importante con este tipo de análisis es que para suficientemente grande N, un algoritmo será más rápido que otro. Al analizar un algoritmo hasta un término como O (nlogn), se sueltan constantes. Al analizar de forma realista el funcionamiento de un algoritmo, esas constantes serán importantes solo para situaciones de n pequeño.
¿Qué significa esto? Eso significa que para ciertos n pequeños, algunos algoritmos son más rápidos. Este article de EmbeddedGurus.net incluye una perspectiva interesante sobre la elección de diferentes algoritmos de clasificación en el caso de un espacio limitado (16k) y un sistema de memoria limitado. Por supuesto, el artículo hace referencia solo a ordenar una lista de 20 enteros, por lo que las órdenes más grandes de n son irrelevantes. Un código más corto y menos consumo de memoria (además de evitar la recursión) fueron, en última instancia, decisiones más importantes.
El tipo de inserción tiene poca sobrecarga, se puede escribir de manera bastante sucinta y tiene varias ventajas clave: es estable y tiene una carcasa de ejecución bastante rápida cuando la entrada está casi ordenada.
Si hablamos de mantener una lista ordenada, no hay ninguna ventaja sobre algún tipo de árbol, simplemente es más lento.
Bueno, tal vez consume menos memoria o es una implementación más simple.
insertar en una lista ordenada implicará una exploración, lo que significa que cada inserto es O (n), por lo tanto, la clasificación n elementos se convierte en O (n^2)
insertar en un recipiente tal como un árbol de equilibrado, es típicamente log (n), por lo tanto, el género es O (n log (n)) que, por supuesto, es mejor.
Pero para las listas pequeñas, apenas hace ninguna diferencia. Puede usar una ordenación por inserción si tiene que escribirla usted mismo sin ninguna biblioteca, las listas son pequeñas y no le importa el rendimiento.
SÍ,
La ordenación por inserción es mejor que la Ordenación rápida en las listas cortas.
De hecho, una ordenación rápida óptima tiene un umbral de tamaño en el que se detiene y, a continuación, toda la matriz se ordena por inserción por encima de los límites del umbral.
también ...
Para mantener un marcador, binario ordenación por inserción puede ser tan bueno como se pone.
Ver this page.
La noción de "marcador", donde los elementos están disponibles uno a la vez, me recuerda un "doble" de esa situación, donde los artículos deben ser devueltos del tipo uno a la vez (como con el tipo de selección). He codificado un tipo NlgN que devuelve primero el primer elemento, segundo el segundo elemento, etc. La sobrecarga de teneduría de libros es bastante horrenda, pero el número de comparaciones es menor que el qsort() de la biblioteca con el que lo comparaté. Comience con todos los nodos en el grupo primario con una puntuación de uno. Repetidamente tome dos elementos con el puntaje más bajo del grupo primario y compárelos ... – supercat
... colocando al "ganador" en el puntaje principal, con el puntaje del perdedor agregado al suyo, y el perdedor en una "reserva" grupo con su puntaje sin modificaciones. Continúe hasta que el grupo primario tenga un elemento. Ese elemento es el mejor, así que déjalo salir, y pasa al grupo primario todos los elementos contra los cuales se ha comparado el elemento ganador. Luego comience a tomar elementos del grupo primario como hasta que solo quede uno (el segundo mejor elemento). En un momento dado, cada elemento en el grupo de reserva será inferior a al menos un elemento en el grupo primario, y no se conocerá ningún elemento en el grupo primario ... – supercat
... será inferior a cualquier otro elemento del grupo . Aunque el grupo primario comenzará con todos los N elementos, los pases posteriores solo incluyen los elementos con los que se comparó el "ganador", por lo que la salida de los artículos después del primero será razonablemente rápida. – supercat
Sí, hay un motivo para utilizar una ordenación de inserción o una de sus variantes.
Las alternativas de clasificación (clasificación rápida, etc.) de las otras respuestas aquí presuponen que los datos ya están en la memoria y listos para funcionar.
Pero si intenta leer una gran cantidad de datos de una fuente externa más lenta (por ejemplo, un disco duro), se desperdicia una gran cantidad de tiempo ya que el cuello de botella es claramente el canal de datos o la unidad. Simplemente no puede mantenerse al día con la CPU. Una serie natural de esperas ocurre durante cualquier lectura. Estas esperas son desperdiciados ciclos de CPU si no los usa para especie a medida que avanza.
Por ejemplo, si usted fuera a hacer que su solución a este ser los siguientes:
- leer un montón de datos en un bucle dedicado a la memoria
- Ordenar que los datos
Usted muy probablemente tomaría más tiempo que si hicieras lo siguiente en dos hilos.
Tema A:
- Leer un dato
- lugar de referencia en la cola FIFO
- (Repetir hasta que los datos agotados por unidad)
Tema B:
- Obtener un dato de la cola FIFO
- insertarlo en el lugar adecuado en su lista ordenada
- (repetir hasta cola vacía y el hilo A dice "hecho").
... lo anterior le permitirá utilizar el tiempo perdido de otra manera. Nota: El hilo B no impide el progreso del hilo A.
Cuando los datos se hayan leído por completo, se habrán clasificado y estarán listos para su uso.
Un concepto importante en el análisis de algoritmos es el análisis asintótico. En el caso de dos algoritmos con diferentes tiempos de ejecución asintóticos, como uno O (n^2) y un O (nlogn) como es el caso con el ordenamiento de inserción y el ordenamiento rápido respectivamente, no está claro si uno es más rápido que el otro.
La distinción importante con este tipo de análisis es que para un N suficientemente grande, un algoritmo será más rápido que otro. Al analizar un algoritmo hasta un término como O (nlogn), se sueltan constantes. Al analizar de forma realista el funcionamiento de un algoritmo, esas constantes serán importantes solo para situaciones de n pequeño.
¿Qué significa esto? Eso significa que para ciertos n pequeños, algunos algoritmos son más rápidos. Este artículo de EmbeddedGurus.net incluye una perspectiva interesante sobre la elección de diferentes algoritmos de clasificación en el caso de un espacio limitado (16k) y un sistema de memoria limitado. Por supuesto, el artículo hace referencia solo a ordenar una lista de 20 enteros, por lo que las órdenes más grandes de n son irrelevantes. Un código más corto y menos consumo de memoria (además de evitar la recursión) fueron, en última instancia, decisiones más importantes.
El tipo de inserción tiene poca sobrecarga, se puede escribir de manera bastante sucinta y tiene varias ventajas clave: es estable y tiene una carcasa de ejecución bastante rápida cuando la entrada está casi ordenada.
Para matrices pequeñas, la ordenación de inserción se realiza más rápido que el quicksort. Java 7 y Java 8 usan el enlace dinámico de doble pivote para ordenar tipos de datos primitivos. Dual pivot quicksort realiza un quicksort típico de un solo pivote. De acuerdo con el algoritmo de quicksort doble pivote:
- Para pequeñas arrays (longitud < 27), utilizar el algoritmo de inserción tipo.
- Elija dos de pivote ...........
Definitivamente ordenación por inserción fuera realiza la clasificación rápida para las pequeñas matrices y es por eso que está interruptor de ordenación por inserción para las matrices de longitud inferior a 27. La razón podría ser que no hay recurrencias en la ordenación por inserción.
Fuente: http://codeblab.com/wp-content/uploads/2009/09/DualPivotQuicksort.pdf
- 1. ¿Alguna vez hay una buena razón para usar eval()?
- 2. Insertion Sort Error
- 3. ActionScript: ¿Hay alguna vez una buena razón para usar 'como' casting?
- 4. ¿Hay alguna buena razón para usar Websockets fuera del navegador?
- 5. ¿Hay alguna razón para usar esto->
- 6. ¿Hay alguna razón para usar System.Uri?
- 7. ¿Hay alguna vez una razón lógica para usar 1 = 1 en una cláusula where?
- 8. ¿Hay alguna razón para lanzar una DivideByZeroException?
- 9. JS doble exclamación: ¿hay alguna buena razón para usarlo?
- 10. ¿Hay alguna razón negativa para usar una solución N-Tier?
- 11. ¿Hay alguna razón para usar propiedades privadas en C#?
- 12. Buena razón para usar java.util.Date en una API
- 13. ¿Hay alguna buena razón para usar el cambio de bit a excepción de la matemática rápida?
- 14. ¿Hay alguna buena razón para usar "printf" en lugar de "imprimir" en java?
- 15. ¿Hay alguna buena razón para usar valores hexadecimales sobre los valores de color RGB en CSS?
- 16. ¿Alguna vez hay una razón para ocultar miembros heredados en una interfaz?
- 17. ¿Hay alguna razón para no usar AssertionHelper con NUnit?
- 18. ¿Hay alguna razón para usar clases en Python si solo hay una clase en el programa?
- 19. ¿Hay alguna razón para usar SGML en lugar de XML?
- 20. ¿Hay alguna razón para no usar las propiedades 'protegidas'?
- 21. ¿Hay alguna razón para no usar "esto" ("Self", "Me", ...)?
- 22. ¿Hay alguna razón para usar Object.create() o new en JavaScript?
- 23. ¿Hay alguna razón para tener una propiedad sin getter?
- 24. Necesito una muy buena razón para usar Python
- 25. ¿Cuál es una buena razón para usar vistas de SQL?
- 26. ¿Alguna razón importante para no usar AJAX?
- 27. ¿Alguna razón para no usar XmlSerializer?
- 28. ¿Alguna vez hay una razón para incluir la línea de shebang en los paquetes de Perl?
- 29. ¿Hay alguna buena razón que no debería usar - (guión) en los nombres de campo en MySQL?
- 30. ¿Hay alguna buena razón para no utilizar unicode en lugar de cadena?
Si va a cargar en una gran cantidad de datos de una fuente externa relativamente lento, como un disco duro, a menudo es mejor utilizar un algoritmo de ordenación-as-you-go para hacer uso de los ciclos desperdiciados involucrados en una CPU a la espera de que la unidad se ponga al día. [Ver mi respuesta a continuación] (http://stackoverflow.com/a/30193315/4229245). –