数组随机排序之洗牌

@TravellerDIV.IO分享了一篇《数组元素随机化排序算法实现》,这篇文章提供了三种数组项随机排序的实现方法:

使用数组sort方法对数组元素随机排序

1 Array.prototype.shuffle = function(n) {
2     var len = this.length ,
3         num = n ? Math.min(n,len) : len,
4         arr = this.slice(0);
5     arr.sort(function(a,b){
6         return Math.random()-0.5;
7     });
8     return arr.slice(0,num-1);
9 }

随机交换数组内的元素

 1 lib = {}
 2 lib.range = function(min,max) {
 3     return min + Math.floor(Math.random()*(max-min+1));
 4 }
 5 
 6 Array.prototype.shuffle = function(n) {
 7     var len = this.length,
 8         num = n ? Math.min(n,len) : len,
 9         arr = this.slice(0),
10         temp,
11         index;
12 
13     for (var i=0;i<len;i++){
14         index = lib.range(i,len-1);
15         temp = arr[i];
16         arr[i] = arr[index];
17         arr[index]=temp;
18     }
19     return arr.slice(0,num);
20 }

随机从原数组抽取一个元素,加入到新数组

 1 lib = {}
 2 lib.range = function(min,max) {
 3     return min+Math.floor(Math.random()*(max-min+1));
 4 }
 5 
 6 Array.prototype.shuffle = function(n) {
 7     var len = this.length, 
 8         num = n ? Math.min(n,len) : len,
 9         arr = this.slice(0),
10         result=[],
11         index;
12 
13     for (var i=0;i<num;i++){
14         index = lib.range(0,len-1-i);
15         // 或者 result.concat(arr.splice(index,1))
16         result.push(arr.splice(index,1)[0]);
17   }
18   return result
19 }

洗牌算法

数组随机排序其基本原理是洗牌算法(Fisher–Yates shuffle):

是一种将有限集合的顺序打乱的一种算法

原理

  • 定义一个数组(shuffled),长度(length)是原数组(arr)长度
  • 取 0 到 index (初始0) 随机值 randshuffled[index] = shuffled[rand]shuffled[rand] = arr[index]
  • index++ ; 重复第二步,直到 index = length -1

就是 shuffled 从 0 到 length-1 的赋值过程,并且新加入的值是 arr[index]shuffled[index] 的值是已赋值的元素中随机值shuffled[rand],因为这样会有两个重复的值,所以 shuffled[rand] 就等于新加入的值 arr[index]

underscore.js 中的 shuffle 方法

 1 function random(min, max) {
 2     if (max == null) {
 3       max = min;
 4       min = 0;
 5     }
 6     return min + Math.floor(Math.random() * (max - min + 1));
 7 };
 8 function shuffle(arr) {
 9   var length = arr.length,
10       shuffled = Array(length);
11   for (var index = 0, rand; index < length; index++) {
12       rand = random(0, index);
13       if (rand !== index) shuffled[index] = shuffled[rand];
14       shuffled[rand] = arr[index];
15     }
16     return shuffled;
17 }

 

实际运用:

1 var arr = [1,2,3,4,5,6,7,8,9];
2 for (var i = 0; i < 10; i++){
3     console.log(shuffle(arr));
4 }

Chrome输出的结果如下:

数组随机排序

还有更简单易理解的写法:

 1 function shuffle(arr) {
 2     var i, 
 3         j,
 4         temp;
 5     for (i = arr.length - 1; i > 0; i--) {
 6         j = Math.floor(Math.random() * (i + 1));
 7         temp = arr[i];
 8         arr[i] = arr[j];
 9         arr[j] = temp;
10     }
11     return arr;
12 };

有关于洗牌算法扩展阅读

 

posted @ 2016-05-23 21:20  待繁华落尽  阅读(463)  评论(0编辑  收藏  举报