Skip to content

Fisher-Yates Shuffle算法

最早的洗牌算法,其原理是从原始数组中随机取一个之前没取过的数字到新的数组中。时间复杂度 O(n^2),空间复杂度 O(n)

特点

  • 随机性。
  • 等概率,即每种结果的出现概率都应相同。

缺点

  • 必须知道数组的长度。

举例👇

假设有一副扑克牌 54张,现在要你把它洗乱,且每张牌都不能在原来的位置,要求是随机的。

算法步骤

  1. 初始化一个数组大小为 n 的数组 arr,已知的。
  2. 从还没处理的数组(假如还剩k个)中,随机产生一个[0, k)之间的数字 r
  3. 剩下的 k 个数中把第 r 个数取出放到新数组里
  4. 重复2、3步骤,直到数字全部取完。
javascript
// 第一步
const poker = [
  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
  23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
  42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
]


function shuffle(arr) {
  let res = []

  // 第四步
  while(arr.length > 0) {
    // 第二步
    const r = parseInt(Math.random() * arr.length)
    // 第三步
    res.push(arr.splice(r, 1)[0])
  }

  return res
}

shuffle(poker)

Released under the MIT License.