Esto probablemente se trata de un poco tarde en el juego en lo que se refiere a su pregunta, pero vamos a ser completa.
Las pruebas son la mejor manera de responder a esta pregunta para la arquitectura, el compilador y la implementación de su computadora. Más allá de eso, hay generalizaciones.
En primer lugar, las colas de prioridad no son necesariamente O (n log n).
Si tiene datos enteros, hay colas de prioridad que funcionan en O (1) hora. La publicación de Beucher y Meyer de 1992 "El enfoque morfológico de la segmentación: la transformación de la cuenca hidrográfica" describe las colas jerárquicas, que funcionan bastante rápido para valores enteros de rango limitado. La publicación de Brown de 1988 "Colas de calendario: una rápida implementación de cola de prioridad de 0 (1) para el problema de conjunto de eventos de simulación" ofrece otra solución que trata bien con rangos de enteros más grandes: dos décadas de trabajo después de la publicación de Brown han producido algunos buenos resultados para hacer números enteros colas de prioridad rápido. Pero la maquinaria de estas colas puede complicarse: los tipos de cubo y los tipos de raíz aún pueden proporcionar una operación O (1). En algunos casos, incluso puede cuantizar datos de coma flotante para aprovechar una cola de prioridad O (1).
Incluso en el caso general de datos de coma flotante, ese O (n log n) es un poco engañoso.El libro de Edelkamp "Búsqueda Heurística: Teoría y Aplicaciones" tiene la siguiente tabla útil que muestra la complejidad del tiempo para diversos algoritmos de cola de prioridad (recuerde, colas de prioridad son equivalentes a la clasificación y gestión montón):
Como se puede ver, muchas colas de prioridad tienen costos de O (log n) no solo para la inserción, sino también para la extracción, ¡e incluso para la administración de colas! Si bien el coeficiente generalmente se descarta para medir la complejidad de tiempo de un algoritmo, aún vale la pena conocer estos costos.
Pero todas estas colas aún tienen complejidades de tiempo que son comparables. ¿Cuál es el mejor? Un documento de 2010 de Cris L. Luengo Hendriks titulado "Revisando colas de prioridad para el análisis de imágenes" aborda esta cuestión.
En la prueba de retención Hendriks', una cola de prioridad se sembró con N números aleatorios en el intervalo [0,50]. El elemento que estaba en la parte superior de la cola se quitó de la cola, se incrementó en un valor aleatorio en el rango [0,2], y luego se puso en cola. Esta operación se repitió 10^7 veces. La sobrecarga de generar los números aleatorios se restó de los tiempos medidos. Las colas de escalera y los montones jerárquicos funcionaron bastante bien con esta prueba.
También se midió el tiempo por elemento para inicializar y vaciar las colas; estas pruebas son muy relevantes para su pregunta.
Como se puede ver, las diferentes colas menudo tenían respuestas muy diferentes a encolamos y desencolado. Estas cifras implican que si bien puede haber algoritmos de cola de prioridad que son superiores para la operación continua, no existe la mejor opción de algoritmo para simplemente llenar y luego vaciar una cola de prioridad (la operación que está haciendo).
Vamos a mirar hacia atrás en sus preguntas:
Lo que es más rápido: la inserción en una cola de prioridad, o clasificar de forma retrospectiva?
Como se muestra arriba, las colas de prioridad se pueden hacer eficientes, pero todavía hay costos de inserción, eliminación y administración. La inserción en un vector es rápida. Es O (1) en tiempo amortizado, y no hay costos de administración, además el vector es O (n) para ser leído.
Ordenar el vector le costará O (n log n) suponiendo que tiene datos de coma flotante, pero esta vez la complejidad no oculta cosas como las colas de prioridad. (Hay que tener un poco de cuidado, sin embargo, Quicksort funciona muy bien con algunos datos, pero tiene una complejidad de tiempo de peor caso de O (n^2). Para algunas implementaciones, este es un riesgo de seguridad serio.)
Me temo que no tengo datos para los costos de clasificación, pero diría que la clasificación retroactiva captura la esencia de lo que intentas hacer mejor y, por lo tanto, es la mejor opción. En función de la complejidad relativa de la gestión de colas de prioridad frente a la clasificación posterior, diría que la clasificación posterior debería ser más rápida. Pero, de nuevo, deberías probar esto.
Estoy generando algunos elementos que debo ordenar al final. Me preguntaba, ¿qué es más rápido en términos de complejidad: insertarlos directamente en una cola de prioridad o una estructura de datos similar, o usar un algoritmo de ordenación al final?
Probablemente este tema esté cubierto anteriormente.
Sin embargo, hay otra pregunta que no hizo. Y tal vez ya sabes la respuesta. Es una cuestión de estabilidad. El C++ STL dice que la cola de prioridad debe mantener un orden "estrictamente débil". Esto significa que los elementos de igual prioridad son incomparables y pueden colocarse en cualquier orden, a diferencia de un "orden total" donde cada elemento es comparable. (Hay una buena descripción del pedido here). En la clasificación, "estricto débil" es análogo a un tipo inestable y "orden total" es análogo a un tipo estable.
El resultado es que si los elementos de la misma prioridad se mantienen en el mismo orden en que los insertó en su estructura de datos, entonces necesita un orden estable o un orden total. Si planea usar C++ STL, entonces tiene solo una opción. Las colas de prioridad utilizan un ordenamiento débil estricto, por lo que son inútiles aquí, pero el algoritmo "stable_sort" en la biblioteca de algoritmo STL hará el trabajo.
Espero que esto ayude. Avíseme si desea una copia de cualquiera de los artículos mencionados o si desea una aclaración. :-)
¿Alguna información sobre la cantidad de datos? ¿necesita una ordenación/clasificación completa o una ordenación parcial/nth_element sería suficiente? – MadH
Necesito un tipo completo, pero no tiene que ser estable. Estoy más interesado en la complejidad que en el rendimiento para un tamaño de problema específico, por lo que no especifiqué ninguno. –
casi un duplicado (pero para Java, por lo que no voté para cerrar): http://stackoverflow.com/questions/3607593/is-it-faster-to-add-to-a-collection-then-sort- it-or-add-to-a-sorted-collection – Thilo