前端排序算法

一.冒泡排序算法

原理:簡單來講就是相鄰兩個元素進行對比,按照你須要的排序方式(升序or降序)進行位置替換,替換時須要額外一個變量看成中間變量去暫存值。shell

總結步驟:數組

     一、外循環是遍歷每一個元素,每次都放置好一個元素;   post

     二、內循環是比較相鄰的兩個元素,把大/小的元素交換到後面;ui

     三、等到第一步中循環好了之後也就說明所有元素排序好spa

function Bubble(arr) { for (let i = 0; i < arr.length; i++) {//遍歷數組每個(回合數) for (let j = 0; j < arr.length - 1 - i; j++) {//真正進行比較,例:i=0時比較第一次,進入第二層循環arr[0]與arr[1]進行比較,符合交換條件即交換,不符合繼續比較 if (arr[j] < arr[j + 1]) { let temp = arr[j + 1]//交換變量 arr[j + 1] = arr[j] arr[j] = temp } } } return arr }

時間複雜度:http://blog.csdn.net/itachi85/article/details/54882603.net

  最好的狀況:數組已經排好序(不用交換元素)----->  時間花銷爲:[ n(n-1) ] /  2;因此最優的狀況時間複雜度爲:O( n^2 )3d

  最差的狀況:也就是開始的時候元素是逆序的,那麼每一次排序都要交換兩個元素,則時間花銷爲:[ 3n(n-1) ] / 2;(其中比上面最優的狀況所花的時間就是在於交換元素的三個步驟);因此最差的狀況下時間複雜度爲:O( n^2 );code

綜上:blog

  最優的時間複雜度爲:O( n^2 ) ;//當使用標誌位方法來判斷你是否排好序時,時間複雜度爲O(n)

       最差的時間複雜度爲:O( n^2 );

       平均的時間複雜度爲:O( n^2 );

加上flag的代碼以下:

function bubbleSort2(arr) {var i = arr.length-1;  //初始時,最後位置保持不變
    while ( i> 0) { var flag= 0; //每趟開始時,無記錄交換
        for (var j= 0; j< i; j++) if (arr[j]> arr[j+1]) { flag= j; //記錄交換的位置,flag以後的均已交換成功
                var tmp = arr[j];
          arr[j]=arr[j+1];
          arr[j+1]=tmp; } i= flag; //爲下一趟排序做準備,只要掃描到flag位置便可 }return arr; }

 

二:選擇排序

原理:首先從原始數組中找到最小的元素,並把該元素放在數組的最前面,而後再從剩下的元素中尋找最小的元素,放在以前最小元素的後面,直到排序完畢

function Choose(arr) { let maxIndex, temp; for (let i = 0; i < arr.length - 1; i++) { maxIndex = i//maxIndex始終做爲最大值的位置索引,
        for (let j = i + 1; j < arr.length; j++) {//當前最大值的後一位開始比較
          if (arr[j] > arr[maxIndex]) {//當後一位大於當前maxIndex
            maxIndex = j//將最大位置的索引值變爲二者中較大的
 } } temp = arr[i]//當前輪次中的i與最大值進行交換,以達成最大值在前的的目的
        arr[i] = arr[maxIndex] arr[maxIndex] = temp } return arr }

時間複雜度:

       平均時間複雜度:O(n*n)

  最好狀況:O(n*n)

  最差狀況:O(n*n)

三:插入排序

原理:一組數據分紅兩組,分別將其稱爲有序組與待插入組。每次從待插入組中取出一個元素,與有序組的元素進行比較,並找到合適的位置,將該元素插到有序組當中。就這樣,每次插入一個元素,有序組增長,待插入組減小。直到待插入組元素個數爲0。

function InsertionSort(array) { var length = array.length; for (var i = 0; i < length - 1; i++) {//i表明已經排序好的序列最後一項下標(第一項已排好序)
        var insert = array[i + 1];//insert爲待插入組的第一項
        var index = i + 1;//記錄要被插入的下標
        for (var j = i; j >= 0; j--) { if (insert > array[j]) //要插入的項比它小/大,日後移動
            array[j + 1] = array[j]; index = j; } } array[index] = insert; } return array; }

時間複雜度:

       平均時間複雜度:O(n*n)

  最好狀況:O(n)

  最差狀況:O(n*n)

 

四:希爾排序(屬於插入排序的一種)

原理:利用步長來進行兩兩元素比較,而後縮減步長在進行排序。

  複製了一個詳細的說明:希爾排序的實質是分組插入排序,該方法又稱縮小增量排序。該方法的基本思想是:先將整個待排元素序列分割爲若干個子序列(由相隔某個‘增量’的元素組成的)分別進行直接插入排序,而後依次縮減增量再進行排序,帶這個序列中的元素基本有序(增量足夠小)時,再對全體元素進行一次直接插入排序。由於直接插入排序在元素基本有序的狀況下(接近最好狀況)效率是很高的,所以希爾排序在時間效率上有較大的提升。 
希爾排序算法實現。

與插入排序的不一樣之處:它會優先比較距離較遠的元素

function shellSort(arr) { let temp, gap = 1; while (gap < arr.length / 3) { gap = gap * 3 + 1//動態定義間隔序列
 } for (gap; gap > 0; gap = Math.floor(gap / 3)) {//控制步長(間隔)並不斷縮小
        for (var i = gap; i < arr.length; i++) {//按照增量個數對序列進行排序
          temp = arr[i] for (var j = i - gap; j >= 0 && arr[j] > temp; j -= gap) {//例:j=0 arr[1]>arr[5]
            arr[j + gap] = arr[j] } arr[j + gap] = temp } } return arr }

 

時間複雜度:

  最佳狀況: O(nlog2 n)

  最壞狀況: O(nlog2 n)

  平均狀況: O(nlog n)

五:歸併排序

原理:採用分治法,先劃分,再合併

 步驟:

     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.依次類推,直到合併到最上層結束,這時數據的排序已經完成了。

function mergeSort(arr) { if (arr.length < 2) { return arr; } //將數組分爲左右兩個子序列
      let middle = Math.floor(arr.length / 2) let left = arr.slice(0, middle) let right = arr.slice(middle) return merge(mergeSort(left), mergeSort(right))//對兩個子序列重複劃分爲兩個進行排序,直到不能劃分
 } function merge(left, right) { let result = [] while (left.length > 0 && right.length > 0) { if (left[0] < right[0]) {//兩兩比較,較小的放入結果數組
          result.push(left.shift())//shift()方法刪除數組第一個元素,並返回被刪除的元素
        } else { result.push(right.shift()) } } /* 當左右數組長度不等.將比較完後剩下的數組項連接起來便可 */  
        return result.concat(left).concat(right); }

時間複雜度:

  最佳狀況:T(n) = O(n)

  最差狀況:T(n) = O(nlogn)

  平均狀況:T(n) = O(nlogn)

六:快速排序

原理:選擇一個基準,將比基準小的放左邊,比基準小的放在右邊(基準處在中間位置)

function quickSort2(arr) { //若是數組<=1,則直接返回
      if (arr.length <= 1) { return arr; } var pivotIndex = Math.floor(arr.length / 2); //找基準,並把基準從原數組刪除
      var pivot = arr.splice(pivotIndex, 1) [0]; //定義左右數組
      var left = []; var right = []; //比基準小的放在left,比基準大的放在right
      for (var i = 0; i < arr.length; i++) { if (arr[i] <= pivot) { left.push(arr[i]); } else { right.push(arr[i]); } } //遞歸
      return quickSort2(left).concat([pivot], quickSort2(right)); }

時間複雜度:

  最佳狀況:T(n) = O(nlogn)

  最差狀況:T(n) = O(n2)

  平均狀況:T(n) = O(nlogn)

排序算法全部時間複雜度及空間複雜度,穩定性等:

 

掘金的這個文章寫的很詳細:https://juejin.im/post/57dcd394a22b9d00610c5ec8

相關文章
相關標籤/搜索