1. 程式人生 > >資料結構與演算法JavaScript描述讀書筆記(高階排序演算法)

資料結構與演算法JavaScript描述讀書筆記(高階排序演算法)

希爾排序

在插入排序的基礎上,只不過比較的步長不一樣,插入排序比較步長一直是1(即一個一個的比較)。希爾排序的步長第一次一般設定為gap=Math.floor(arr.length/2),之後依次將步長設定為gap/2,直到步長變為1,這個時候徹底轉化成插入排

測試時間普通排序演算法10萬條資料就已經時間很久了,但是希爾排序都可以處理千萬條資料,時間大概為2000毫秒,一億條資料沒有測試

以下的資料是測試10萬條資料的普通排序演算法和1000萬的希爾排序演算法,時間真的差的很多

時間複雜度:

穩定性:不穩定

function shellSort(arr){
    //外層迴圈為步長,直到步長為1不再迴圈
    for(var gap = Math.floor(arr.length/2);gap >0;gap = Math.floor(gap/2)){
        //步長為gap的插入排序,方法同插入排序,只不過原來的j--變成了 j -= gap
        for(var i=gap;i<arr.length;i++){
            var temp = arr[i];
            for(var j = i-gap;j>=0;j -= gap){
                if(temp >= arr[j]){
                    break;
                }else{
                    arr[j+gap] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }
    return arr;
}

歸併排序

實現原理:將一系列排好序的子序列合併成一個大的完整有序序列

時間複雜度:

穩定性:

測試千萬資料過程中發現時間沒有希爾排序快

//合併兩個陣列
function mergeArray(left,right){
    var arr = [];
    var i=0;
    var j=0;
    while(i<left.length && j<right.length){
        if(left[i] <= right[j]){
            arr.push(left[i]);
            i++;
        }else{
            arr.push(right[j]);
            j++;
        }
    }
    while(i<left.length){
        arr.push(left[i]);
        i++;
    }
    while(j<right.length){
        arr.push(right[j]);
        j++;
    }
    return arr;
}
//將陣列分成兩個陣列(一直遞迴的分,知道length長度為1則不分),並將這兩個陣列有序的組合起來
function mergeSort(arr){
    var mid,left,right;
    if(arr.length<=1){
        return arr;
    }else{
        mid = Math.floor(arr.length/2);
        left = arr.slice(0,mid);
        right = arr.slice(mid);
        return mergeArray(mergeSort(left),mergeSort(right));
    }
}

快速排序

快速排序是處理大資料最快的排序演算法之一,它是一種分而治之的演算法。通過遞迴的方法將資料分解為包含較小元素和較大元素的不同子序列,不斷重複直到資料有序

演算法首先在列表中選擇一個元素作為基準值。資料排序圍繞基準值進行,將列表中小於基準值的元素移到陣列的底部,將大於基準值的元素移到陣列的頂部

快速排序適合大型資料,小的資料反而效率不高

時間複雜度:

穩定性:

function qSort(arr){
    if(arr.length <= 1){
        return arr;
    }
    var left = [];
    var right = [];
    var mid = arr[0];
    for(var i=1;i<arr.length;i++){
        if(arr[i] <= mid){
            left.push(arr[i]);
        }else{
            right.push(arr[i]);
        }
    }
    return qSort(left).concat(mid,qSort(right));
}

存在問題:當資料量大的時候提示too much recursion