2010-10-20 14 views
7

Por lo que puedo decir, inplace_merge hace exactamente lo mismo que ordenar, excepto que solo funciona en ciertas circunstancias (cuando el contenedor ya está en dos partes ordenadas).C++ STL :: ¿cuál es la diferencia entre inplace_merge y sort

En otras palabras, ¿hay una diferencia entre estos dos:

int first[] = {1,3,5,7}; 
int second[] = {2,4,6,8}; 
vector<int> v(8); 
vector<int>::iterator it; 
copy(first,first+4, v.begin()); 
copy(second,second+4, v.begin()+4); 

inplace_merge(v.begin(), v.begin()+4, v.end()) 

.

int first[] = {1,3,5,7}; 
int second[] = {2,4,6,8}; 
vector<int> v(8); 
vector<int>::iterator it; 
copy(first,first+4, v.begin()); 
copy(second,second+4, v.begin()+4); 

sort(v.begin(), v.end()) 

¿La única diferencia será la eficiencia?

Respuesta

10

Su complejidad no es lo mismo:

  • sort() tiene un peor caso de O(N²), dependiendo del algoritmo de clasificación que utiliza su aplicación STL.

  • inplace_merge() tiene un peor caso de O(N*log(N)) y una mejor caso de O(N-1), por lo que nunca será más lenta que sort() (con las mismas entradas).

También, como otros han señalado, inplace_merge() es stable: preserva el orden de las partidas cuya clave de clasificación es la misma. sort() no garantiza esto. stable_sort(), y su peor de los casos es la complejidad O(N*log(N)²).

+1

-1 La pregunta es, ¿el escenario propuesto por OP es el peor caso para cualquiera de los algoritmos? Comparar las complejidades del peor caso no tiene sentido cuando se considera un escenario específico. –

+1

@ Space_c0wb0y no está de acuerdo, la pregunta parece ser más general y luego utiliza el escenario como ejemplo, que dice que las complejidades no necesariamente significan que inplace_merge nunca será más lento que el ordenamiento, y esta respuesta no considera la estabilidad –

+0

Gracias. La única otra cosa que estoy poniendo en esta respuesta es el hecho de que inplace_merge es estable, mientras que sort (no stable_sort) es inestable en la forma en que ordena. Pero lo que has respondido a la pregunta. Debería haber leído completamente el "manual" en cplusplus.com :) –

5

dos diferencias:

  • estabilidad: inplace_merge es un algoritmo estable (se mantener los elementos iguales en el mismo orden tanto dentro subintervalos y entre usted dos gamas originales).
    Por lo tanto, puede haber una ligera diferencia en el resultado cuando se trata de contenedores de tipos no primitivos o cuando se extrae su función de clasificación. Por supuesto, con el contenedor de int Egers, usted no notará ninguna diferencia :)
  • eficiencia: como se dijo, dado el hecho de que ya tiene dos subconjuntos ordenados, inplace_merge se debe implementar de una manera diferente y por lo tanto, probablemente sea más eficiente. El solo hecho de que esta función exista mucho.
+0

_ "inplace_merge' debe implementarse de una manera diferente y, por lo tanto, probablemente sea más eficiente" _. Eso está mal. El estándar no aplica un algoritmo específico para 'inplace_merge', solo el efecto final y la complejidad del algoritmo. Además, de hecho, 'sort' probablemente será más eficiente que' inplace_merge'. Es decir, 'inplace_merge' tiene una mejor garantía de peor caso que' sort', pero 'sort' tiene un mejor rendimiento desde un punto de vista estadístico, en un gran conjunto de varias entradas. Sin embargo, esto no es una garantía estándar: el énfasis está en _probablemente_. – wilhelmtell

+0

@wilhelmtell, lo que quiero decir cuando digo * debe * es como en * debe haber algo *. – Benoit

+0

@wilhelmtell: esperaría que 'inplace_merge' siempre fuera más rápido que' std :: sort'. El estándar no exige un rendimiento exacto (el compilador puede agregar sentencias de sueño arbitrarias), pero como los escritores del compilador no escriben código incorrecto, la implementación obvia de 'inplace_merge' nunca será peor que cualquier implementación de' std :: sort' . –

3

Los sort tipo Método 2 ordenadas elementos en el rango (primera, última) en orden ascendente.
inplace_search fusiona el rango de 2 ordenados (primera, medio) y (segundo, apellido) en una gama ordenada combinada (primera, última).


Para inplace_merge para ser eficiente, las 2 sub-intervalos debe ser clasificadas (esa es la diferencia). Además, inplace_merge es teóricamente unstable, (pero stable en C++) pero requiere memoria eficiente para hacer (último - primero) - 1 comparaciones de lo contrario es similar a sort (que hace comparaciones O (n log n)).

+0

-1 Igual que para Frèdèric: Comparar las peores complejidades de caso del algoritmo no tiene sentido cuando se considera un escenario específico, que podría no ser el peor de los casos para ninguno de los algoritmos. –

+0

Buena edición, eliminó el -1. –

+0

Gracias, extraño, todavía tengo el -1, y mi puntaje sigue siendo el mismo (en 4493) ... solo digo, ..... lol –

Cuestiones relacionadas