在 JavaScript 中,最常用且公平的洗牌算法是 Fisher-Yates 洗牌算法(也称 Knuth 洗牌算法),核心逻辑是从数组末尾向前遍历,每次将当前元素与前面随机位置的元素交换,确保每个元素被打乱的概率均等。
1. 基础实现(原地洗牌)
直接修改原数组,空间复杂度为 O(1),适合对性能要求较高的场景。
javascript:
/**
* Fisher-Yates 原地洗牌算法
* @param {Array} arr - 待洗牌的数组
* @returns {Array} 洗牌后的数组(与原数组引用相同)
*/
function shuffleArray(arr) {
// 从数组最后一位开始向前遍历
for (let i = arr.length - 1; i > 0; i--) {
// 生成 [0, i] 范围内的随机整数(确保每个位置概率均等)
const randomIndex = Math.floor(Math.random() * (i + 1));
// 交换当前元素与随机位置元素
[arr[i], arr[randomIndex]] = [arr[randomIndex], arr[i]];
}
return arr;
}
// 测试
const arrs= ["猫", "狗", "兔", "仓鼠", "鹦鹉"];
shuffleArray(arrs);
console.log(arrs); // 示例输出:["兔", "猫", "鹦鹉", "狗", "仓鼠"](每次结果不同)
2. 非原地洗牌(不修改原数组)
通过创建原数组的副本进行洗牌,避免改变原数组,适合需要保留原始数据的场景。
javascript:
/**
* Fisher-Yates 非原地洗牌算法
* @param {Array} arr - 待洗牌的数组

最低0.47元/天 解锁文章
3161

被折叠的 条评论
为什么被折叠?



