Hier ist eine einfache (aber effektiv) Umsetzung des Fischer-Yates/Knuth Shuffle:
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;
}
Oder eine leichte Variation:
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;
}
Da es sich um ein O (n) Operation, es ist der effizienteste Weg, eine Liste zu mischen. Da alle Elemente in der Liste verschoben werden müssen, ist es nicht möglich, eine Liste effizienter zu mischen als O (n).
Ich habe einen kleinen Leistungstest gemacht, indem ich eine Million Elemente tausendmal mixte, wobei ich diese Methode und die aktuell akzeptierte Antwort (LINQ OrderBy) benutzte, und dies ist ungefähr 15 mal (!) Schneller.
Wollen Sie eigentlich die * effizienteste Lösung * oder möchten Sie eine * effizientere Lösung *? Weil es Algorithmen gibt, die sogar noch effizienter sind, als Fischer-Yates, vorausgesetzt, Sie sind bereit, bestimmte schöne Eigenschaften aufzugeben, wie zB fehlende Voreingenommenheit. (Nicht, dass Fischer-Yates wie unten implementiert ist unvoreingenommen; es ist stark voreingenommen.) –
@Eric: Fischer-Yates _ist_ unvoreingenommen. Die unten angegebene Implementierung ist falsch, wie Sie angemerkt haben. Natürlich gibt es effizientere Implementierungen, wenn Sie bereit sind, Verzerrungen zu haben. Zum Beispiel, tun _nothing_ überhaupt. Ich verstehe wirklich nicht, was du meinst. Das OP hat nichts spezifiziert, und es ist vernünftig (IMO) anzunehmen, dass sie nach einem einheitlichen Shuffle suchen. –
Ist das wirklich * vernünftig? Der betreffende Shuffle-Algorithmus ist für Mediendateien gedacht. Man könnte das Shuffle dazu neigen, höher bewertete Songs häufiger zu wiederholen. –