labuladong 洗牌算法详解:你会排序,但你会打乱吗?
所以我们面临两个问题:
\1. 什么叫做「真的乱」?
\2. 设计怎样的算法来打乱数组才能做到「真的乱」?
这种算法称为「随机乱置算法」或者「洗牌算法」。
一、洗牌算法
此类算法都是靠随机选取元素交换来获取随机性,直接看代码(伪码),该算法有 4 种形式,都是正确的:
// 得到一个在闭区间 [min, max] 内的随机整数
int randInt(int min, int max);
// 第一种写法
void shuffle(int[] arr) {
int n = arr.length();
/******** 区别只有这两行 ********/
for (int i = 0 ; i < n; i++) {
// 从 i 到最后随机选一个元素
int rand = randInt(i, n - 1);
/*************************/
swap(arr[i], arr[rand]);
}
}
// 第二种写法
for (int i = 0 ; i < n - 1; i++)
int rand = randInt(i, n - 1);
// 第三种写法
for (int i = n - 1 ; i >= 0; i--)
int rand = randInt(0, i);
// 第四种写法
for (int i = n - 1 ; i > 0; i--)
int rand = randInt(0, i);