系列文章目录
● 算法笔记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相同
三、写在后面
文本是对内容是对山东师范大学徐老师的课件内容整理归纳及补充,仅供自己复习参考,如有侵权立即删除。