2010-10-20 4 views
7

Per quanto ne so, inplace_merge fa esattamente la stessa cosa di ordinamento, tranne che funziona solo in determinate circostanze (quando il contenitore è già in due parti ordinate).STL di C++ :: qual è la differenza tra inplace_merge e ordinamento

In altre parole, v'è una differenza tra questi due:

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()) 

L'unica differenza sarà l'efficienza?

risposta

10

La loro complessità non è la stessa:

  • sort() ha un caso peggiore di O(N²), a seconda dell'algoritmo di ordinamento utilizzato dal implementazione STL.

  • inplace_merge() ha un caso peggiore di O(N*log(N)) e un caso migliore di O(N-1), quindi sarà mai più lento rispetto sort() (con gli stessi input).

Inoltre, come altri hanno sottolineato, inplace_merge() è stable: conserva l'ordinamento dei prodotti la cui chiave di ordinamento è lo stesso. sort() non lo garantisce. stable_sort() e la sua complessità nel caso peggiore è O(N*log(N)²).

+1

-1 La domanda è, è lo scenario che l'OP ha proposto il caso peggiore per uno degli algoritmi? Confrontare le complessità del caso peggiore non ha senso quando si considera uno scenario specifico. –

+1

@ Space_c0wb0y non sono d'accordo, la domanda sembra essere più generale e in seguito utilizza lo scenario come esempio, che dice che le complessità non significano necessariamente inplace_merge non sarà mai più lento di sort, e questa risposta non considera la stabilità –

+0

Grazie. L'unica altra cosa che sto mettendo in questa risposta è il fatto che inplace_merge è stabile, mentre sort (non stable_sort) è instabile nel modo in cui lo ordina. Ma a cosa avevi risposto la domanda. Dovrei aver letto completamente il "manuale" su cplusplus.com :) –

5

due differenze:

  • stabilità: inplace_merge è un algoritmo stabile (si manterranno elementi uguali nello stesso ordine sia all'interno sottointervalli e tra voi due gamme originali).
    Quindi, potrebbe esserci una leggera differenza nel risultato quando si gestiscono contenitori di tipi non primitivi, o quando la funzione di ordinamento è estratta. Naturalmente, con il contenitore di int Egers, non si noterà alcuna differenza :)
  • efficienza: come hai detto, dato il fatto che si dispone già di due sottoinsiemi ordinati, inplace_merge deve essere attuata in un modo diverso e quindi probabilmente sarà più efficiente. Il solo fatto che esista questa funzione dice molto.
+0

_ "' inplace_merge' deve essere implementato in un modo diverso e sarà quindi probabilmente più efficiente "_. È sbagliato. Lo standard non applica un algoritmo specifico per 'inplace_merge', solo l'effetto di fine riga e la complessità dell'algoritmo. Inoltre, in effetti 'sort' sarà _probabilmente_ più efficiente di' inplace_merge'. Cioè, 'inplace_merge' ha una migliore garanzia di caso peggiore di' sort', ma 'sort' ha una prestazione migliore da un punto di vista statistico, su una vasta serie di vari input. Questa non è una garanzia standard però: l'enfasi è su _probably_. – wilhelmtell

+0

@wilhelmtell, cosa intendo quando dico * deve * è come in * ci deve essere qualcosa *. – Benoit

+0

@wilhelmtell: mi aspetterei che 'inplace_merge' sia sempre più veloce di' std :: sort'. Lo standard non impone prestazioni esatte (il compilatore può aggiungere istruzioni di sospensione arbitrarie), ma poiché gli scrittori di compilatori non stanno intenzionalmente scrivendo codice errato, l'implementazione ovvia di "inplace_merge" non sarà mai peggiore di qualsiasi implementazione di 'std :: sort' . –

3

I sort metodo tipo 2 scelti elementi nell'intervallo (primo, ultimo) in ordine crescente.
inplace_search fonde la gamma 2 filtrate (primo, centrale) e (centrale, last) in un intervallo ordinato combinato (primo, ultimo).


Per inplace_merge per essere efficiente, i 2 subrange deve essere ordinati (che è la differenza). Inoltre, inplace_merge è teoricamente unstable, (ma stable in C++) ma richiede una memoria efficiente per eseguire (ultimo - primo) - 1 confronti altrimenti è simile all'ordinamento (che fa confronti O (n log n)).

+0

-1 Come per Frèdèric: Confrontare le complessità del caso peggiore dell'algoritmo non ha senso quando viene considerato uno specifico scenario, che potrebbe non essere il caso peggiore per nessuno degli algoritmi. –

+0

Buona modifica, rimosso il -1. –

+0

Grazie, strano, ho ancora il -1, e il mio punteggio è sempre lo stesso (su 4493) ... solo dicendo, ..... lol –