javascript優化插入排序算法

此次優化排序算法呢是爲了在優先隊列中使用這個算法。算法

我從網絡上隨便複製一種排序算法,隨便找的,首先看看他的實現。數組

function Insertion(arr) {
    let len = arr.length;
    let preIndex, current;
    for (let i = 1; i < len; i++) {
        preIndex = i - 1;
        current = arr[i];
        while (preIndex >= 0 && current > arr[preIndex]) {
            arr[preIndex + 1] = arr[preIndex];
            preIndex--;
        }
        arr[preIndex + 1] = current;
    }
    return arr;
}
複製代碼

下面是測試隨機生成數組的函數:網絡

function randomArr(len, start, end) {
    let arr = [];
    while (arr.length < len) {
        let d = Math.round(Math.random() * (end - start) + start);
        arr.push(d);
    }
    return arr;
}
複製代碼

下面是測試函數,經過執行下面的函數能夠獲得對應的時間:dom

function test(n, start, end) {
    console.time();
    let a = randArr(n, start, end);
    let b = Insertion(a);
    console.timeEnd()
}
複製代碼

其中n表明數組的個數,startend表明數組的開始和結束,也就是區間。函數

下面是我優化後的函數:測試

function insertSort(arr = []) {
    let sortArr = [];
    // 當數組的長度小於2的時候
    if (arr.length >= 2) {
        if (arr[0] < arr[1]) {
            sortArr.push(arr[1], arr[0]);
        } else {
            sortArr.push(arr[0], arr[1]);
        }
    } else {
        sortArr.push(...arr);
    }
    for (let i = 2; i < arr.length; i++) {
        let lPos = 0;       // 左邊
        let rPos = sortArr.length; // 右邊
        let j = Math.floor((rPos - lPos) / 2);
        while (rPos - lPos !== 1) {
            if (arr[i] > sortArr[j]) {
                rPos = j;
            } else if (arr[i] < sortArr[j]) {
                lPos = j;
            } else {
                lPos = j - 1;
                rPos = j;
            }
            j = Math.floor((rPos + lPos) / 2); // j的值是這二者之間的值
        }
        if (arr[i] > sortArr[j]) {          // 最後判斷與j位置的值,誰大誰小
            sortArr.splice(j, 0, arr[i]);   // 大則在當前位置插入
        } else {
            sortArr.splice(j + 1, 0, arr[i]);// 小則在下一個位置插入
        }
    }
    return sortArr;
}
複製代碼

函數的實現比前一種要複雜一些。整體優化的思路在於第二層。也就是在找插入位置的時候我是經過二分搜索的方式進行的,這樣的時間負責度,差很少是nlogn級別的。跟前一種n^2級別要好一些,固然不能跟快速排序相提並論,之因此沒有選擇快速排序是由於快速排序的穩定性很差。而我要實現的優先隊列對穩定性要求高。優化

下面分別是10萬 - 50萬的測試結果,越到後面的數據次數越少(多條測試使用的逗號隔開的)。我這樣的對比並不是嚴格意義上的控制變量法,可是因爲我執行屢次獲得的結果幾乎類似,因此基本上能夠說明優化的效果。ui

// (100000數據量)
test(Insertion, 100000, 0, 10000); // 3.057, 3.101s, 3.072s, 3.078s
test(insertSort, 100000, 0, 10000);// 737.965ms, 764.219ms, 732.931ms, 739.714ms
複製代碼
// (200000數據量)
test(Insertion, 200000, 0, 10000); // [12.464s]
test(insertSort, 200000, 0, 10000);// [4.506s]
複製代碼
// (300000數據量)
test(Insertion, 300000, 0, 10000); // 27.746s,28.024s
test(insertSort, 300000, 0, 10000);// 10.432s,10.695s
複製代碼
// (400000數據量)
test(Insertion, 400000, 0, 10000); // 50.283s
test(insertSort, 400000, 0, 10000);// 16.581s
複製代碼
// (500000數據量)
test(Insertion, 500000, 0, 10000); // 1:18.815 (m:ss.mmm),1:19.075 (m:ss.mmm)
test(insertSort, 500000, 0, 10000);// 43.778s, 44.420s
複製代碼
相關文章
相關標籤/搜索