17

可能重复:
在 C# 中随机化一个 List<T>

我有一个列表,其中包含数千个 FilePath 到音频文件的位置,并且想知道哪种方法是“洗牌”列表的最有效方法?

任何帮助是极大的赞赏 :)

谢谢

4

4 回答 4

13

Fisher-Yates Shuffle或也称为 Knuth shuffle。

于 2010-02-20T04:17:43.623 回答
8

这是 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;
}

或稍有变化:

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;
}

由于这是一个 O(n) 操作,因此它是洗牌列表的最有效方式。由于列表中的所有项目都必须有机会被移动,因此不可能比 O(n) 更有效地打乱列表。

我使用这种方法和当前接受的答案(LINQ OrderBy)将一百万个项目每一个洗牌一千次,进行了一个小型性能测试,这大约快了 15 倍(!)。

于 2010-02-20T04:49:56.943 回答
5

myList.OrderBy(Guid.NewGuid())

于 2010-02-20T04:21:54.140 回答
0

我将 Jon Skeet 的这个问题的解决方案添加到我的扩展库中。我实现的方法既采用外部随机数生成器,又使用默认实现(随机)创建一个。

于 2010-02-20T04:55:21.417 回答