經常使用的js排序算法

插入排序

圖

算法描述:算法

  1. 從第一個元素開始,該元素能夠認爲已經被排序
  2. 取出下一個元素,在已經排序的元素序列中從後向前掃描
  3. 若是該元素(已排序)大於新元素,將該元素移到下一位置
  4. 重複步驟 3,直到找到已排序的元素小於或者等於新元素的位置
  5. 將新元素插入到該位置後
  6. 重複步驟 2~5
var arr = [5, 6, 3, 1, 8, 7, 2, 4];
for(let i = 1;i<arr.length;i++){
    let myIndex = i;
    console.log('次數:'+i);
    for(let j = i-1 ; j >= 0 ; j -- ){
        console.log('單次比較數據:'+arr[myIndex]+'---'+arr[j])
        if(arr[myIndex] < arr[j]){
            [arr[myIndex],arr[j]] = [arr[j],arr[myIndex]];
            myIndex = j;
        }else{
          break;
        }
        console.log('數組'+arr);
    }
}

時間複雜度 O(n^2)
運行過程
clipboard.png數組

選擇排序

tu

算法描述函數

  • 直接從待排序數組中選擇一個最小(或最大)數字,放入新數組中。
  • 假定第一個數字是最小的,而後依次和後面的比較,哪一個小哪一個就記錄當前那個的下標。
  • 記錄完下標了以後替換第一個和那個最小數字的位置
  • 依次執行上述步驟,只不過最小的位置依次累加
var arr = [5, 6, 3, 1, 8, 7, 2, 4];
for(let i = 0; i < arr.length - 1;i++){
    console.log('次數'+Number(i+1))
    let minIndex = i;
    for(let j = i ;j < arr.length - 1; j++){
         console.log('單次比較數據:'+arr[minIndex]+'---'+arr[j+1])
         if(arr[minIndex] > arr[j+1]){
            minIndex = j+1;
         }
    }
    [arr[minIndex],arr[i]] = [arr[i],arr[minIndex]];
    console.log('數組'+arr);

}

時間複雜度 O(n^2)ui

運行過程
clipboard.pngspa

冒泡排序

tu

就幾種算法來看,感受冒泡是比較慢的

算法描述:3d

  1. 比較相鄰的元素。若是第一個比第二個大,就交換他們兩個。
  2. 對每一對相鄰元素做一樣的工做,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。
  3. 針對全部的元素重複以上的步驟,除了最後一個。
  4. 持續每次對愈來愈少的元素重複上面的步驟,直到沒有任何一對數字須要比較。
var arr = [5, 6, 3, 1, 8, 7, 2, 4];
let count = 0;
for(let i = arr.length ; i > 0; i --){
    console.log('次數'+i);
    for(let j = 1; j < i; j ++){
        console.log('單次比較數據:'+arr[j]+'----'+arr[j-1])
        if(arr[j] < arr[j-1]){
            [arr[j],arr[j-1]] = [arr[j-1],arr[j]]
        }
    }
    console.log(arr);
}

時間複雜度 O(n^2)code

運行過程
clipboard.pngblog

歸併排序

t

歸併排序的圖可能一下看不懂,是由於圖表明的是運行的過程,主要看算法描述

歸併排序:其基本思想是分治策略,先進行劃分,而後再進行合併。
假設要對數組C進行歸併排序,步驟是:
1.先將C劃分爲兩個數組A和B(即把數組C從中間分開)
2.再分別對數組A、B重複步驟1的操做,逐步劃分,直到不能再劃分爲止(每一個子數組只剩下一個元素),這樣,劃分的過程就結束了。
如: [12 20 30 21 15 33 26 19 40 25]
劃分爲: [12 20 30 21 15] [33 26 19 40 25]排序

[12 20]      [30 21 15]       [33 26]       [19 40 25]
     [12]  [20]   [30]  [21 15]     [33]  [26]    [19]    [40 25]
     [12]  [20]   [30] [21] [15]    [33]  [26]    [19]   [40] [25]

3.而後從下層往上層不斷合併數組,每一層合併相鄰的兩個子數組,合併的過程是每次從待合併的兩個子數組中選取一個最小的元素,而後把這個元素放到合併後的數組中,不斷重複直到把兩個子數組的元素都放到合併後的數組爲止。
4.依次類推,直到合併到最上層結束,這時數據的排序已經完成了。ip

var arr = [5, 6, 3, 1, 8, 7, 2, 4,9];
function mergeSort(arr){
    if(arr.length === 1){
        return arr;
    }
    let midIndex = Math.floor(arr.length / 2);
    let leftArr = arr.slice(0,midIndex);
    let rightArr = arr.slice(midIndex);
    console.log('拆分數組'+leftArr+'------'+rightArr)
    return mergeFn(mergeSort(leftArr),mergeSort(rightArr));
}.
function mergeFn(left,right){
    let tmp = [];
    console.log(left + '----' + right);
    while (left.length && right.length) {
        console.log('單次比較數據:'+left[0]+'和'+right[0]+'誰小誰所在的數組就被shift掉一個')
        if (left[0] < right[0]){
          tmp.push(left.shift());
        }
        else{
          tmp.push(right.shift());
        }
        console.log(tmp);
    }
    let arra = tmp.concat(left, right);
    console.log('本次比較完畢:'+arra);

    return arra;

}
mergeSort(arr);

時間複雜度 O(nlogn)

運行過程,看了運行過程就能看懂圖了,也知道js函數裏的參數有函數的狀況下的執行順序是自左向右
clipboard.png
clipboard.png

快速排序

tt

圖上的運行方式是按照基準是第0號位算的,看起來稍微有點亂,不過只要知道快排是怎麼算的就行了

算法描述:

  • 在數據集之中,選擇一個元素做爲」基準」(pivot)。
  • 全部小於」基準」的元素,都移到」基準」的左邊;全部大於」基準」的元素,都移到」基準」的右邊。這個操做稱爲分區 (partition)操做,分區操做結束後,基準元素所處的位置就是最終排序後它的位置。
  • 對」基準」左邊和右邊的兩個子集,不斷重複第一步和第二步,直到全部子集只剩下一個元素爲止。
var arr = [5, 6, 3, 1, 8, 7, 2, 4];
function quickSort(arr){
    if(arr.length <= 1){
        return arr;
    }
    //找基準
    let midIndex = Math.floor(arr.length/2);
    //剔除基準值
    let midNum = arr.splice(midIndex,1)[0];
    console.log('基準值:'+midNum);
    let leftArr = [],rightArr=[];
    for(let i = 0 ; i < arr.length; i++){
        //小於基準的進左邊,大於的進右邊
        arr[i] < midNum ? leftArr.push(arr[i]) : rightArr.push(arr[i])
    }
    console.log('小於基準值的數組:'+leftArr);
    console.log('大於基準值的數組:'+rightArr);
    return quickSort(leftArr).concat(midNum,quickSort(rightArr));
}
quickSort(arr);

時間複雜度 O(nlogn)

運行過程
clipboard.png
這個運行過程是按照基準爲0號位算的;

總結

能夠看到,快速排序和歸併排序是比較快。並且快排更容易理解更好寫一些。

相關文章
相關標籤/搜索