码迷,mamicode.com
首页 > 编程语言 > 详细

关于洗牌算法的错误认识

时间:2018-05-08 22:15:09      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:log   let   pre   自己   javascrip   排除   重复   OLE   asc   

下面是我之前一直使用的一个洗牌算法:

    let arr = [1,2,3,4,5,6,7,8,9];

    Array.prototype.shuffle = function() {
      let temp = this;
      for (let i = 0; i < temp.length; i++) {
        let index       = Math.floor(Math.random()*temp.length);
        let itemAtIndex = temp[index];
        temp[index]     = temp[i]
        temp[i]         = itemAtIndex;
      }  
      return this;
    }
    console.log(arr.shuffle());

但仔细想想,其实这是非常不合理的,因为已经交换过的位置,下次仍然可能会被选上。

比较好的做法是排除已经交换过的位置,将剩下的位置洗牌,如下:

    /*
      1. 选中第一个元素,将其与n个元素中的任意一个交换(包括自己)。这时可以确定第一个元素
      2. 选中第二个元素,将其与n-1个元素中的任意一个交换(包括自己)。确定第二个元素
      3. 重复上面步骤,直到剩下一个。
      4. 该算法事件复杂度为O(n),无偏差,各元素随机概率相等
    */
    let arr = [1,2,3,4,5,6,7,8,9];

    Array.prototype.shuffle = function() {
      let temp = this;
      for (let i = temp.length - 1; i >= 0; i--) {
        let index       = Math.floor(Math.random()*(i+1));
        let itemAtIndex = temp[index];
        temp[index]     = temp[i]
        temp[i]         = itemAtIndex;
      }  
      return this;
    }
    console.log(arr.shuffle());

  

关于洗牌算法的错误认识

标签:log   let   pre   自己   javascrip   排除   重复   OLE   asc   

原文地址:https://www.cnblogs.com/guohaoyun/p/9010958.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!