Fisher-Yates 洗牌算法(也称为 Knuth 洗牌)是一种高效且公正的随机洗牌算法,用于将数组或列表中的元素随机重新排列。
🎯 算法原理
核心思想:从后往前遍历数组,将当前元素与随机位置的一个元素交换。
📝 算法步骤
原始版本:
1 | // 从后往前遍历 |
现代版本(Knuth 改进):
1 | // 从前往后遍历(更直观) |
🔢 示例演示
假设数组:[1, 2, 3, 4, 5]
步骤:
- i=0: j=随机(0-4),假设 j=2 → 交换 arr[0] 和 arr[2]
- 数组变为:
[3, 2, 1, 4, 5]
- 数组变为:
- i=1: j=随机(1-4),假设 j=3 → 交换 arr[1] 和 arr[3]
- 数组变为:
[3, 4, 1, 2, 5]
- 数组变为:
- i=2: j=随机(2-4),假设 j=2 → 无交换
- 数组保持:
[3, 4, 1, 2, 5]
- 数组保持:
- i=3: j=随机(3-4),假设 j=4 → 交换 arr[3] 和 arr[4]
- 最终结果:
[3, 4, 1, 5, 2]
- 最终结果:
💻 代码实现
PHP 实现:
1 | function fisherYatesShuffle(array &$array): void |
JavaScript 实现:
1 | function fisherYatesShuffle(array) { |
✅ 算法优势
- 均匀分布:每个排列出现的概率相等
- 时间复杂度:O(n) - 非常高效
- 空间复杂度:O(1) - 原地操作
- 无偏性:真正的随机洗牌
❌ 对比其他方法的劣势
错误方法示例:
1 | // ❌ 错误:非均匀分布 |
Fisher-Yates 是洗牌算法的黄金标准,在需要真正随机排列时应该优先选择它。