JS--排序算法之計數和基數排序


JS-排序算法之計數和基數排序

計數排序

利用數組的index是天然有序的特征來排序. 例如: 已知一個亂序數組的范圍是0~10,長度未知, 我們只需要遍歷一遍數組,點出每個值出現的次數,並用一個新數組來存儲這個次數,就能做到排序. 假如數字1出現3次, 那么新數組newAry[1]=3, 在新數組遍歷的時候輸出3次"1"

  • 時間復雜度O(n~K)
  • 穩定的排序算法
  • 性能: 由於是非比較排序, 速度快於其他任何排序算法,
  • 缺點: 需要知道數組值的范圍, 且不適用於范圍波動很大但長度小的數組
    • 例如: 數組長度10, 但是值的范圍在 0~1000000, 計數排序用來計數的數組將會很大
  • 特點: 先遍歷數組計算數值出現次數, 然后就排序好了...
    function countSort(ary) {
        let newAry = new Array(ary.length).fill(0);
        for (const value of ary) {
            newAry[value]++;
        }
        ary = [];
        // 給ary重新賦值
        for(var i =0; i<newAry.length; i++) {
            // 循環數字次數
            for(var k = newAry[i]; k>0; k--) {
                ary.push(i);
            }
        }
        newAry = null;
        return ary;
    }

效果演示:

計數排序.gif

基數排序

從左到右按位排序, 先排個位, 再排十位,百位... 需要用到計數排序的方法-使用數組計數

    function radixSort(ary) {
    // 獲取最大值
    let maxNum = Math.max.apply(Math, ary);
    let t = 1,
        bucketAry = new Array(10), // 0~9的數組,用來計算數字出現次數
        temp = new Array(ary.length); // 交換數組, 用來臨時存儲排序的數
    // 這一步是計算最大數有多少位,這個位數就是要循環的次數
    while ((maxNum /= 10) >= 1) {
        t++;
    }
    let rate = 1,
        K= null;
    for (let i = 1; i <= t; i++) {
        // 計數數組歸零
        bucketAry.fill(0);
        // 清點數字次數
        ary.forEach((item) => {
            // 求數字最后一位的值
            k = Math.floor(item / rate) % 10;
            bucketAry[k]++;
        });
        // 通過數字次數得到該數字應該在數組中的位置
        bucketAry.reduce((total, item, index) => {
            bucketAry[index] = total + item;
            return total + item
        });
        // 通過計算的順序將ary中數存入temp數組中
        for (let j = ary.length - 1; j >= 0; j--) {
            k = Math.floor(ary[j] / rate) % 10;
            temp[bucketAry[k] - 1] = ary[j];
            bucketAry[k]--;
        }
        // 將temp相同位置的值負值給ary, 不能直接 ary = temp
        ary = ary.map((item, index)=>temp[index]);
        rate *= 10;
    }
    temp = null;
    bucketAry = null;
    return ary;
}

效果演示:

基數排序.gif


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM