JS隨機洗牌演算法之數組隨機排序,js洗牌演算法

來源:互聯網
上載者:User

JS隨機洗牌演算法之數組隨機排序,js洗牌演算法

推薦閱讀:JavaScript學習筆記之數組的增、刪、改、查

JavaScript學習筆記之數組求和方法

JavaScript學習筆記之數組隨機排序

洗牌演算法是一個比較形象的術語,本質上讓一個數組內的元素隨機排列。舉例來說,我們有一個如所示的數組,數組長度為 9,數組內元素的值順次分別是 1~9:

從上面這個數組入手,我們要做的就是打亂數組內元素的順序:


代碼實現

維基百科上的 Fisher–Yates shuffle 詞條對洗牌演算法做了詳細介紹,下面示範的演算法也是基於其中的理論編寫的:

Array.prototype.shuffle = function() {var input = this;for (var i = input.length-1; i >=0; i--) {var randomIndex = Math.floor(Math.random()*(i+1)); var itemAtIndex = input[randomIndex]; input[randomIndex] = input[i]; input[i] = itemAtIndex;}return input;}var tempArray = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]tempArray.shuffle();// and the result is...alert(tempArray); 

在上面的代碼中,我們建立了一個 shffle() 方法,該方法用於隨機排列數組內的元素。此外,我們將該方法掛載在了 Array 對象的原型下面,所以任何數組都可以直接調用該方法:

var tempArray = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]tempArray.shuffle(); 

工作原理

看完代碼之後,讓我們看看它對數組都做了寫什麼。首先,該方法選中數組的最後一個元素:

接下來確定挑選隨機元素的範圍,從數組的第一個元素到上一步選中的元素都屬於這一範圍:

確定範圍後,從中隨機挑選一個數,這裡假設隨機選中的元素為 4:

然後交換最後一個元素和隨機選中的元素的值:

上面的交換完成後,相當於我們完成了對數組最後一個元素的隨機處理。接下來選中數組內倒數第二的元素:

之所以從後往前處理,是因為這樣便於確定隨機播放的範圍。這次我們假定隨機到的元素為 2:


接著交換倒數第一個元素和 2 號元素的值,完成對倒數第二個元素隨機排列的處理。然後是選中倒數第三個元素,重複之前的操作:

剩下的就是一些重複性的工作,不多做介紹了。

分析代碼

在上一節給各位用圖例示範了洗牌流程,下面我們從代碼本身看看洗牌流程。先從 shuffle 函數說起吧:

Array.prototype.shuffle = function() {var input = this;for (var i = input.length-1; i >=0; i--) {var randomIndex = Math.floor(Math.random()*(i+1)); var itemAtIndex = input[randomIndex]; input[randomIndex] = input[i]; input[i] = itemAtIndex;}return input;} 

shuffle 函數掛載在 Array 對象的原型之下,便於數組直接調用該函數。在 shuffle 函數內部,this 引用的就是調用該 shuffle 的數組:

var input = this;

在上面的代碼中,我用一個新的變數引用 this,也就是調用 shuffle 函數的數組。下一步,看一下 for 迴圈內都幹了什麼:

for (var i = input.length-1; i >=0; i--) {var randomIndex = Math.floor(Math.random()*(i+1)); var itemAtIndex = input[randomIndex]; input[randomIndex] = input[i]; input[i] = itemAtIndex;}

該迴圈用於遍曆所有數組內的所有元素,並進行隨機交換。注意,遍曆順序是從後往前進行的,也就是說從 input.length-1 位置的元素開始,知道遍曆到數組中的第一個元素。遍曆過程中的位置由變數 i 指定。

這裡的變數 i 就是上面圖例中被選中的元素:

洗牌演算法

接下來,使用了兩行代碼在指定範圍內挑選一個隨機元素:

var randomIndex = Math.floor(Math.random()*(i+1)); var itemAtIndex = input[randomIndex];

變數 randomIndex 儲存了一個隨機數,該隨機數可以用作數組的索引,進而提取一個隨機元素。注意,該隨機數的最大值並不是數組的長度,而是變數 i 的值。

確定了隨機元素的索引之後,用新的變數儲存該元素的值,然後交換選中元素和隨機元素的值:

var itemAtIndex = input[randomIndex];input[randomIndex] = input[i]; input[i] = itemAtIndex;

在這三行代碼中,第一行使用新的變數儲存了隨機元素的值;第二行將選中元素 input[i] 的值賦給隨機元素 input[randomIndex];第三行就隨機元素的值 itemAtIndex 賦給選中元素 input[i]。本質上是一個互換兩個元素的值的過程,並不難理解。

至此,迴圈內的邏輯就介紹完了,剩下的都是重複操作。

隨機性測試


是使用 Highcharts 製作的隨機性測試圖表,以可視化的方式校正本文中洗牌演算法的隨機性。每次重新整理頁面都會重新計算和產生該圖表。

產生的資料是這樣計算而來的:首先建立一個數組(使用的數組為 [0, 1, 2 ... 18, 19, 20]),然後使用本文中的洗牌演算法重新排序,排序完成後記錄每一個元素的值……以此步驟執行 100000 次,最後對同一索引位置上的數值進行求和。如此執行 10000 次之後,索引之間的總值應該相差不大。

由計算可得:

以上內容是小編給大家介紹的JS隨機洗牌演算法之給數組隨機排序的相關敘述,希望對大家有所協助!

您可能感興趣的文章:
  • php實現簡單洗牌演算法
  • javascript隨機之洗牌演算法深入分析
  • C#實現洗牌演算法
  • C#實現對數組進行隨機排序類執行個體
  • php數組隨機排序實現方法
  • JavaScript實現數組隨機排序的方法
  • javascript數組隨機排序執行個體分析
  • 基於php實現隨機合并數組並排序(原排序)
  • JavaScript學習筆記之數組隨機排序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.