三种经典的洗牌算法

参考原文链接:https://blog.csdn.net/qq_25026989/article/details/89512769

问题描述:洗牌算法是将原来的数组进行打散,使原数组的某个数在打散后的数组中的每个位置上等概率的出现。

主要有3中经典的洗牌算法:

1.抽牌

            1.初始化原始数组和新数组,原始数组长度为n(已知);

            2.从还没处理的数组(假如还剩k个)中,随机产生一个[0, k)之间的数字p(假设数组从0开始);

            3.从剩下的k个数中把第p个数取出;

            4.重复步骤2和3直到数字全部取完;

            5.从步骤3取出的数字序列便是一个打乱了的数列。

           时间复杂度为O(n*n),空间复杂度为O(n).

2.换牌原地打乱顺序):

             1. 建立一个数组大小为 n 的数组 arr,分别存放 1 到 n 的数值;
             2. 生成一个从 0 到 n - 1 的随机数 x;
             3. 输出 arr 下标为 x 的数值,即为第一个随机数;
             4. 将 arr 的尾元素和下标为 x 的元素互换;
             5. 同2,生成一个从 0 到 n - 2 的随机数 x;
             6. 输出 arr 下标为 x 的数值,为第二个随机数;
             7. 将 arr 的倒数第二个元素和下标为 x 的元素互换;
                ……
             如上,直到输出 m 个数为止

             时间复杂度为O(n),空间复杂度为O(1)

            缺点必须知道数组长度n.原始数组被修改了,这是一个原地打乱顺序的算法,算法时间复杂度也从Fisher算法的 O(n2)提              升到了O(n)。由于是从后往前扫描,无法处理不知道长度或动态增长的数组。

3.插牌(蓄水池抽样):  

          1.先选中第1到k个元素,作为被选中的元素。然后依次对第k+1至第N个元素做如下操作:

          2.每个元素都有k/x的概率被选中,然后等概率的(1/k)替换掉被选中的元素。其中x是元素的序号。

          从N个元素中随机等概率取出k个元素(洗牌发牌可以认为k=1),N长度未知。在o(n)时间内对n个数据进行等概率随机            抽取。如果数据集合的量特别大或者还在增长(相当于未知数据集合总量),该算法依然可以等概率抽样.

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值