洗牌算法简单分析

关于洗牌算法,网上有比较多的实现,一个比较简单直接的实现如下:


void ShuffleArray_Fisher_Yates(char* arr, int len)
{
    int i = len, j;
    char temp;
 
    if ( i == 0 ) return;
    while ( --i ) {
        j = rand() % (i+1);
        temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}
对这段代码简单分析,我们以52张牌为例,分别编号为0到51,经过一轮洗牌之后,第n张牌最终停留在n位置的概率应该是1/52。根据算法,我们逐一分析:

对于第51张牌,很明显停留在51位置的概率是1/52;

对于第50张牌,在上一轮交换中,它不能被换到第51位置,概率为51/52,这一轮它需要停留在50位置,因此,概率为1/51,所以总的概率为1/52;

对于第49张牌,在第一轮中,它不能被交换到51位置,概率51/52,第二轮不能交换到50,概率50/51,第三轮,概率1/50,所以总的概率 51/52×50/51×1/50 = 1/52;

以此类推,可以得出 每一张牌停留在原始位置的概率都是1/52;


当然,也可以说经过一次洗牌之后,停留在第n个位置上的牌的编号为m的概率为1/52;



由于random算法并不是真随机数,因此所得到的概率并不完全符合1/52;


如果要严格证明,需要证明出现任何一种排列的时候,其概率为1/n!;


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值