Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

实现洗牌算法 #24

Open
lxinr opened this issue Apr 27, 2019 · 0 comments
Open

实现洗牌算法 #24

lxinr opened this issue Apr 27, 2019 · 0 comments

Comments

@lxinr
Copy link
Owner

lxinr commented Apr 27, 2019

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
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant