算法笔记02|洗牌算法(附C++代码)

系列文章目录

● 算法笔记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张扑克牌:

  1. 随机选取一张,如3,与最后一张未交换的扑克牌(10)交换;
    在这里插入图片描述交换后

  2. 再次随机选取一张扑克牌,如8,与最后一张未交换的扑克牌(9)交换;
    在这里插入图片描述在这里插入图片描述

  3. 不断循环直到全部交换完毕。
    在这里插入图片描述

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]之间的随机数:

  1. 获取范围[low, high]的长度L=high-low+1
  2. rand()%L产生0~L-1之间的随机数
  3. 最后加上low

4. 算法复杂度

复杂度:T(n) = n
实际为 n-1,但渐进情况下与n相同


三、写在后面

文本是对内容是对山东师范大学徐老师的课件内容整理归纳及补充,仅供自己复习参考,如有侵权立即删除。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值