# 洗牌算法

9 篇文章 0 订阅
6 篇文章 0 订阅

基本概念

等概率将将一个数组N打乱,概率每次都是1/N,加上

方法一

全局洗牌, 从 0到N-1的数组下标,每次随机产生两个0到 N-1之间的数,进行交换

void get_rand_number(int array[], int length)
{
	int index;
	int value;
	int median;
 
	if(NULL == array || 0 == length)
		return ;
 
	/* 每次发牌的时候任意分配待交换的数据 */
	for(index = 0; index < length; index ++){
		value = rand() % length;
 (在这里要取余数,主要是     )
		median = array[index];
		array[index] = array[value];
		array[value] = median;
	}
## j

局限性

多次重复洗牌,

Knuth Shuffle洗牌算法

局部洗牌, 从比如选定位置N-1,随机产生0到N-2之间的一个数,将下标为该数的值与N-1上面的位置进行交换(只考虑为洗好的牌)
,N-1位置上面的数就洗好了,洗一次就不考虑
for i 从 N-1 到 1,
随机数 0到 i(可以等于i) 随机产生一个数 j
交换i和j之间连个鬼数

首先我们生成一个大小为54的数组,数组排列为1~54
a)同样,首先我们生成一个大小为54的数组,数组排列为1~54
b)索引牌从1开始,到54结束。这一次索引牌只和剩下还没有洗的牌进行交换, value = index + rand() %(54 - index
c)等到所有的索引牌都洗好之后,一副牌就弄好了

void get_rand_number(int array[], int length)
{
	int index;
	int value;
	int median;
	
	if(NULL == array || 0 == length)
		return ;
	
	/* 发牌的时候对于已经分配的数据不再修改 */
	for(index = 0; index < length; index ++){
		value = index + rand() % (length - index);
		
		median = array[index];
		array[index] = array[value];
		array[value] = median;
	}
}

Knuth Shuffle

每次从未处理的数组中随机取一个元素,然后把该元素放到数组的尾部,即数组的尾部放的就是已经处理过的元素,这是一种原地打乱的算法,每个元素随机概率也相等,时间复杂度从 Fisher 算法的 O(n2)提升到了 O(n)

选取数组(长度n)中最后一个元素(arr[length-1]),将其与n个元素中的任意一个交换,此时最后一个元素已经确定
选取倒数第二个元素(arr[length-2]),将其与n-1个元素中的任意一个交换
重复第 1 2 步,直到剩下1个元素为止

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值