| 最近遇到这样一个问题:生成 1 - N 的随机排列。这是一个比较常见的问题,生成一个有限集合的随机排列的时候就要用到。一种 naive 的算法是: for i = 1..n do r = 1..n 之间的随机数 while (r 已经被选择) do r = 1..n 之间的随机数 end ar[i] = r 将 r 标记为已被选择 end 这种算法的问题是,当可供选择的数很少的时候(极端情况是只剩最后一个),大量的时间都浪费在 while 循环上了,理论上平均时间复杂度达到 O(n2) ,而且还需要额外空间记录是否已经使用。 实际上,前人早已研究过这个问题。Random Shuffle 算法可以在 O(n) 的时间内随机打乱一个数组,所以只需要把 1..N 保存在一个数组中,再 shuffle 这个数组即可。实现方法参见维基百科 Fisher–Yates shuffle 。正确性证明参见 Knuth 的《计算机程序设计艺术(第二卷):半数值算法》。 不少语言已经在标准库中包含了这个函数: Python import random random.shuffle(ar) Java import java.util.Collections; Collections.shuffle(List<?> list); C++ #include <algorithm> const int N = 8; int ar[] = {1, 2, 3, 4, 5, 6, 7, 8}; random_shuffle(ar, ar + N); Lua 标准库中没有这个函数,我的实现: -- random shuffle a table in place function shuffle(t) f |


