Ecco un semplice (ma efficace) attuazione del riordino Fischer-Yates/Knuth:
Random rnd = new Random();
for (int i = files.Length; i > 1; i--) {
int pos = rnd.Next(i);
var x = files[i - 1];
files[i - 1] = files[pos];
files[pos] = x;
}
O una leggera variazione:
Random rnd = new Random();
for (int i = 1; i < files.Length; i++) {
int pos = rnd.Next(i + 1);
var x = files[i];
files[i] = files[pos];
files[pos] = x;
}
Poiché si tratta di un O (n) operazione, è il modo più efficace per mischiare una lista. Poiché tutti gli elementi nell'elenco devono avere la possibilità di essere spostati, non è possibile mescolare un elenco in modo più efficiente di O (n).
Ho eseguito un piccolo test delle prestazioni mescolando un milione di articoli mille volte ciascuno utilizzando questo metodo e la risposta attualmente accettata (LINQ OrderBy), e questo è circa 15 volte (!) Più veloce.
Vuoi davvero la * soluzione più efficiente possibile * o vuoi una * soluzione accettabilmente efficiente *? Perché ci sono algoritmi ancora più efficienti che Fischer-Yates ti ha fornito di voler abbandonare certe proprietà, come la mancanza di pregiudizi. (Non che Fischer-Yates come implementato sotto è imparziale, è profondamente prevenuto.) –
@Eric: Fischer-Yates _is_ imparziali. L'implementazione indicata di seguito non è corretta, come hai notato. Naturalmente ci sono implementazioni più efficienti se si è disposti ad avere pregiudizi. Ad esempio, fai _nothing_ a tutti. Non capisco davvero il tuo punto. L'OP non ha specificato nulla ed è ragionevole (IMO) presumere che stiano cercando uno shuffle uniforme. –
È * veramente * ragionevole? L'algoritmo shuffle in questione è per i file multimediali. Si potrebbe voler spingere lo shuffle a ripetere più frequentemente le canzoni più apprezzate. –