实现洗牌算法
lxinr opened this issue · 0 comments
lxinr commented
Fisher-Yates算法
大致流程:
- 写下从 1 到 N 的数字
- 取一个从 1 到剩下的数字(包括这个数字)的随机数 k
- 从低位开始,得到第 k 个数字(这个数字还没有被取出),把它写在独立的一个列表的最后一位
- 重复第 2 步,直到所有的数字都被取出
- 第 3 步写出的这个序列,现在就是原始数字的随机排列
function shuffle(arr){
var result = [],
random;
while(arr.length > 0){
random = Math.floor(Math.random() * arr.length);
result.push(arr[random])
arr.splice(random, 1)
}
return result;
}在方法中使用了
splice,因此其时间复杂度为O(n2)
Knuth-Durstenfeld算法
该方法是为计算机设计的,具体为每次从未处理的数组中随机取一个元素,然后把该元素放到数组的尾部,即数组的尾部放的就是已经处理过的元素,该方法复杂度为
O(n)
function shuffle(arr){
let n = arr.length, random
while(0 !== n){
random = Math.floor(Math.random() * n--) // 向下取整
[arr[n], arr[random]] = [arr[random], arr[n]] // 变量互换
}
return arr
}