Molto probabilmente da Josh Bloch § :
Ho scritto questi metodi, quindi suppongo di essere qualificato per rispondere. È vero che non esiste un unico miglior algoritmo di ordinamento. QuickSort ha due principali carenze rispetto a Mergesort:
Non è stabile (come notato da parsifal).
Non garantisce n log n prestazioni; può degradare a prestazioni quadratiche su input patologici.
La stabilità non è un problema per i tipi primitivi, poiché non esiste una nozione di identità distinta dall'uguaglianza (di valore). E la possibilità di un comportamento quadratico non era considerata un problema in pratica per l'implementazione di Bentely e McIlroy (o successivamente per Dual Pivot Quicksort ), motivo per cui queste varianti QuickSort sono state utilizzate per i tipi primitivi.
La stabilità è un grosso problema quando si ordinano oggetti arbitrari. Ad esempio, supponi di avere oggetti che rappresentano i messaggi di posta elettronica e di ordinarli prima per data, poi per mittente. Ti aspetti che vengano ordinati per data all'interno di ciascun mittente, ma ciò sarà vero solo se l'ordinamento è stabile. Ecco perché abbiamo scelto di fornire un ordinamento stabile (Merge Sort) per ordinare i riferimenti agli oggetti. (Tecnicamente parlando, più ordinamenti stabili sequenziali producono un ordinamento lessicografico sulle chiavi nell'ordine inverso degli ordinamenti: l'ordinamento finale determina la sottochiave più significativa.)
È un bel vantaggio collaterale che Merge Sort garantisce n log n (tempo) prestazioni indipendentemente dall'input. Ovviamente c'è un lato negativo: l'ordinamento rapido è un ordinamento "sul posto": richiede solo il log in uno spazio esterno (per mantenere lo stack di chiamate). Unisci, ordina, d'altra parte, richiede O (n) spazio esterno. La variante TimSort (introdotta in Java SE 6) richiede sostanzialmente meno spazio (O (k)) se l'array di input è quasi ordinato.
Inoltre, è rilevante quanto segue :
L'algoritmo utilizzato da java.util.Arrays.sort e (indirettamente) da java.util.Collections.sort per ordinare i riferimenti agli oggetti è un "mergesort modificato (in cui l'unione viene omessa se l'elemento più alto nella sottolista inferiore è minore di l'elemento più basso nella sottolista superiore). " È un ordinamento stabile e ragionevolmente veloce che garantisce prestazioni O (n log n) e richiede O (n) spazio aggiuntivo. Ai suoi tempi (è stato scritto nel 1997 da Joshua Bloch), è stata una buona scelta, ma oggi possiamo fare molto meglio.
Dal 2003, l'ordinamento elenco di Python utilizza un algoritmo noto come timsort (dal nome di Tim Peters, che lo ha scritto). È un mergesort iterativo stabile, adattivo che richiede molto meno di n confronti log (n) quando viene eseguito su array parzialmente ordinati, offrendo prestazioni paragonabili a un mergesort tradizionale quando viene eseguito su array casuali. Come tutti i Mergesort appropriati, il Timsort è stabile e viene eseguito nel tempo O (n log n) (caso peggiore). Nel peggiore dei casi, timsort richiede spazio di archiviazione temporaneo per n / 2 riferimenti a oggetti; nel migliore dei casi, richiede solo una piccola quantità di spazio costante. Confrontalo con l'implementazione corrente, che richiede sempre spazio aggiuntivo per n riferimenti a oggetti, e batte n log n solo su elenchi quasi ordinati.
Timsort è descritto in dettaglio qui:
http://svn.python.org/projects/python/trunk/Objects/listsort.txt .
L'implementazione originale di Tim Peters è scritta in C. Joshua Bloch l'ha portata da C a Java e ha testato, valutato e messo a punto ampiamente il codice risultante. Il codice risultante è un sostituto immediato di java.util.Arrays.sort. Su dati altamente ordinati, questo codice può essere eseguito fino a 25 volte più velocemente dell'implementazione corrente (sulla VM del server HotSpot). Su dati casuali, le velocità della vecchia e della nuova implementazione sono comparabili. Per elenchi molto brevi, la nuova implementazione è sostanzialmente più veloce della vecchia anche su dati casuali (perché evita la copia non necessaria dei dati).
Inoltre, vedere Java 7 utilizza Tim Sort per i Method Arrays.Sort? .
Non esiste un'unica scelta "migliore". Come per molte altre cose, si tratta di compromessi.