Dimensione pedagogica
Per la sua semplicità, il metodo di partizionamento di Lomuto potrebbe essere più semplice da implementare. C'è un bel aneddoto nella programmazione Pearl di Jon Bentley sull'ordinamento:
“La maggior parte delle discussioni su Quicksort utilizzano uno schema di partizionamento basato su due indici in avvicinamento [...] [ie Hoare's]. Sebbene l'idea di base di questo schema sia semplice, ho sempre trovato i dettagli difficili - una volta ho trascorso la maggior parte dei due giorni inseguendo un bug nascosto in un breve ciclo di partizionamento. Un lettore di una bozza preliminare si è lamentato del fatto che il metodo standard a due indici è in realtà più semplice di quello di Lomuto e ha abbozzato un po 'di codice per chiarire il punto; Ho smesso di occuparmi di aver trovato due bug. "
Dimensione delle prestazioni
Per un uso pratico, la facilità di implementazione potrebbe essere sacrificata per motivi di efficienza. Su base teorica, possiamo determinare il numero di confronti tra elementi e swap per confrontare le prestazioni. Inoltre, il tempo di esecuzione effettivo sarà influenzato da altri fattori, come le prestazioni di memorizzazione nella cache e le previsioni errate del ramo.
Come mostrato di seguito, gli algoritmi si comportano in modo molto simile su permutazioni casuali ad eccezione del numero di swap . Lomuto ha bisogno di tre volte più di Hoare!
Numero di confronti
n−1n
Numero di swap
Il numero di swap è casuale per entrambi gli algoritmi, a seconda degli elementi dell'array. Se assumiamo permutazioni casuali , ovvero tutti gli elementi sono distinti e ogni permutazione degli elementi è ugualmente probabile, possiamo analizzare il numero atteso di swap.
1,…,n
Metodo di Lomuto
jA[j]x1,…,nx−1xx−1x
{1,…,n}1n
1n∑x=1n(x−1)=n2−12.
n
Metodo Hoare
x
ijxij
x
Hyp(n−1,n−x,x−1)n−xx−1(n−x)(x−1)/(n−1)x
Infine, eseguiamo nuovamente la media su tutti i valori pivot per ottenere il numero complessivo previsto di swap per il partizionamento di Hoare:
1n∑x=1n(n−x)(x−1)n−1=n6−13.
(Una descrizione più dettagliata può essere trovata nella tesi del mio maestro , pagina 29.)
Pattern di accesso alla memoria
Entrambi gli algoritmi utilizzano due puntatori nell'array che lo scansionano in sequenza . Pertanto entrambi si comportano in modo quasi ottimale nella memorizzazione nella cache wrt.
Elementi uguali ed elenchi già ordinati
Come già accennato da Wandering Logic, le prestazioni degli algoritmi differiscono più drasticamente per gli elenchi che non sono permutazioni casuali.
n/2
0ijO(nlogn)
0A[j] <= x
i=nΘ(n2)
Conclusione
Il metodo di Lomuto è semplice e facile da implementare, ma non dovrebbe essere utilizzato per implementare un metodo di ordinamento delle librerie.
A[i+1] <= x
. In una matrice ordinata (e dati i perni scelti ragionevolmente) Hoare non fa praticamente swap e Lomuto fa una tonnellata (una volta che j diventa abbastanza piccolo di tutto il restoA[j] <= x
). Cosa mi manca?