Fisher-Yates Shuffle洗牌算法
在程序开发的过程中,我们可能经常会遇到数组乱序的需求,比如从题库中随机抽取题目、歌曲随机播放、或者随机展示一些用户信息这些,我们往往需要把原始数据进行打乱,然后利用打乱后的结果进行展示。
提到打乱顺序,我们往往首先想到的是利用数组的sort,通过传入返回值随机的比较函数,简洁的将数组顺序打乱。
function shuffle(arr) {
return arr.sort(()=> Math.random() > 0.5);
}
但是由于V8引擎中sort的实现方式,此方法并不能真正的将数组打乱,或者说打的不够乱,所以我们今天分享Fisher–Yates Shuffle算法,今天我们经常说起的Fisher-Yates Shuffle算法其实经过Knuth 和 Durstenfeld改良过后的算法,比起Fisher等人原始的算法,在原始数组上进行交互,可以省去额外O(n)的空间。
具体的思路是将指针指向数组的最后一个元素,从前面的元素中随机取出一个元素进行置换,完成后,指针向前移动,依次完成置换。此算法的javascirpt如下,供大家参考。
function shuffle(array) {
var m = array.length, t, i;
while (m) {
i = Math.floor(Math.random() * m--);
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
}