數組打亂算法

一、常規算法算法

function shuffle(array) {
    var copy = [],
          n = array.length,
          i;
    while(n) {
        i = Math.floor(Math.random() * array.length);
        if (i in array) {
            copy.push(array[i]);
            delete array[i];
            n--;
        }
    }
    return copy;
}

這個方法有個很大的問題在於: delete array[i] 會將array的第i個元素設置爲空,即刪除後的值爲undefined,而數組長度並不會改變,因此每次隨機的時候頗有可能還會隨機到這個序號,雖然代碼中有if(i in array) 來避免空值存入新數組,可是徒增了沒必要要的循環,下降了效率;而且還有會存在永遠運行不完的可能!由於隨機數有可能一值會隨機到已經置空的數據!數組

這個方法不是太可取!dom

二、改進的作法性能

function shuffle(array) {
    var copy = [],
          n = array.length,
          i; 
    while (n) {
        i = Math.floor(Math.random() * n--);
        copy.push(array.splice(i, 1)[0]);
    }
    return copy;
}

此方法的重點在於 array.splice(i, 1)。即將隨機出來的數據從原數組中剔除,這樣下一次隨機的時候就不可能會取到這個值了!而且n--保證了循環不會永遠運行!
優化

不過,該方法splice刪除數組元素會致使刪除位置以後的全部元素要作shift操做來向前補充,增長了算法的複雜度。spa

三、進一步優化code

 

function shuffle(array) {
    var m = array.length,
          t, i;
    while(m) {
        i = Math.floor(Math.random() * m--);
        t = array[m];
        array[m] = array[i];
        array[i] = t;
    }
    return array;
}

 

由於咱們要的目的是打算數組的排序,因此打亂後的數組的長度應該是跟原數組長度同樣的,因此,隨機從數組中抽出一個元素,而後與最後一個元素交換,至關於把這個隨機抽取的元素放到數組最後面去,表示它已經被隨機過了,同時被換走的那個元素(原來在最後的那元素)跑到前面去了,會在後續的重複操做中被隨機掉。一輪操做事後,下一輪咱們只在剩下的n-1個元素中進行相同的操做,直到隨機到第一個。blog

附加:排序

function shuffle(array) {
    return array.sort(function(){
        return Math.random() - 0.5;
    });
}

結合js自帶的sort() 方法來實現,這個方法雖然看似簡潔不少(其實只是js後臺運行,源碼sort()方法十分複雜),可是性能卻不如上面那種方法!由於隨着數組元素越多,其隨機性會變差。源碼

相關文章
相關標籤/搜索