系列文章目录
● 算法笔记01|欧几里得GCD算法(附C++代码)
● 算法笔记02|洗牌算法(附C++代码)
一、洗牌问题的定义
通俗地说,洗牌(Shuffle)问题就是将排好序的扑克牌打乱,且打乱后的次序不可预测。

形式化来说,洗牌问题就是将n个排好序的数字或符号打乱,使排序次序随机。
二、洗牌算法
1. 算法思想
算法的主要思想为随机选取一个元素与最后一个未交换的元素交换,最终令全部元素被交换。
具体思想:
① 首先从1~n之间取一个随机数字k1,将第k1个数字与第n个数字交换。
② 再从1~n-1之间取一个随机数字k2,将第k2个数字与第n-1个数字交换。
③ 在第i轮时,从1~n-(i-1)之间取一个随机数字ki,将第ki个数字与第n-(i-1)个数字交换。
④ 循环进行n-1轮后结束。
2. 实现举例
当前按序排放的有10张扑克牌:
-
随机选取一张,如3,与最后一张未交换的扑克牌(10)交换;


-
再次随机选取一张扑克牌,如8,与最后一张未交换的扑克牌(9)交换;


-
不断循环直到全部交换完毕。

3. 算法代码(c++)
代码如下:
//n为最大序号,p为随机选取的序号
for( int i = n - 1; i >= 1; i--){
p = RandIntRange(0, i);
if(p != i)
swap(a[p], a[i]);
}
此处的RandIntRange函数可以实现生成范围
[low, high]之间的随机数:
- 获取范围
[low, high]的长度L=high-low+1- 用
rand()%L产生0~L-1之间的随机数- 最后加上
low
4. 算法复杂度
复杂度:
T(n) = n
实际为 n-1,但渐进情况下与n相同
三、写在后面
文本是对内容是对山东师范大学徐老师的课件内容整理归纳及补充,仅供自己复习参考,如有侵权立即删除。
本文围绕洗牌算法展开,先介绍洗牌问题,即把排好序的数字或符号打乱使次序随机。接着阐述洗牌算法思想,通过随机选取元素与最后未交换元素交换实现打乱。还给出实现举例,最后展示C++代码并分析算法复杂度,内容源于课件整理。
&spm=1001.2101.3001.5002&articleId=109412595&d=1&t=3&u=4e379988a40c407a835f0bdd24ffad89)
587

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



