數組隨機排序之洗牌

@TravellerDIV.IO分享了一篇《數組元素隨機化排序算法實現》,這篇文章提供了三種數組項隨機排序的實現方法:javascript

使用數組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):html

是一種將有限集合的順序打亂的一種算法html5

原理

  • 定義一個數組(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]java

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輸出的結果以下:shell

數組隨機排序

還有更簡單易理解的寫法:數組

 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 };

有關於洗牌算法擴展閱讀

相關文章
相關標籤/搜索