淺解前端必須掌握的演算法(一):氣泡排序

程式猿何大叔發表於2018-06-22

前言

雖然前端面試中很少會考到演算法類的題目,但是你去大廠面試的時候就知道了,對基本演算法的掌握對於從事電腦科學技術的我們來說,還是必不可少的,每天花上 10 分鐘,瞭解一下基本演算法概念以及前端的實現方式。

另外,掌握了一些基本的演算法實現,對於我們日常開發來說,也是如虎添翼,能讓我們的 js 業務邏輯更趨高效和流暢。

演算法介紹

氣泡排序很簡單,就是陣列中的相鄰元素,兩兩比較,數值或者 Unicode 碼小的元素往前排。

冒泡演算法排序圖

具體實現指導如下:

  1. 比較相鄰兩個元素,若前一個比後一個大,則交換位置;
  2. 第一輪結束之後,最後一個元素的值是最大的;
  3. 接著開始第二輪,但是不用再比較最後一個元素了;
  4. 第一輪除外,以後的每一輪都比前一輪少比較一次;

具體實現

var bubbleSort = function (arr){
  var i, j, m;
  var len = arr.length;
  if (len <= 1) {
    return arr;
  }

  for (i=0; i<len-1; i++) {
    for (j=0; j<len-i-1; j++) {
      if (arr[j] > arr[j+1]) {
        m = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = m;
      }
    }
  }
  return arr;
};
複製程式碼

演算法改進

如果陣列原本的順序就是冒泡的,又或者僅做完前面寥寥幾次就已經達到效果了,那後續的比較工作就顯得有些多餘了,如何對以上演算法進行改進?

我們可以在某一輪的迴圈比較結束後,如果沒有發生任何的元素交換,則可以認為該陣列已經達到預期效果,不必再繼續下一輪的比較了。

var bubbleSort = function (arr){
  var start = +new Date();
  var i, j, m, noswap;
  var len = arr.length;
  if (len <= 1) {
    return arr;
  }

  for (i=0; i<len-1; i++) {
    noswap = true;
    for (j=0; j<len-i-1; j++) {
      if (arr[j] > arr[j+1]) {
        m = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = m;
        noswap = false;
      }
    }
    if (noswap) {
      break;
    }
  }

  // 當 arr 的長度越長,時間差越明顯
  console.log(+new Date() - start);
  return arr;
};
複製程式碼

時間度複雜度分析

分析時間複雜度就按最壞的情況來,即待排序表是完全逆序的情況。 假設陣列中共有 n 個元素,第一輪需要比較 n-1 次,第二輪需要比較 n-2 次,第三輪需要比較 n-3 次,以此類推,最後一輪需要比較 1 次,共比較 n-1 輪,所以是個等差數列,運用等差數列求和公式,能計算出如下時間複雜度:

淺解前端必須掌握的演算法(一):氣泡排序

因此總的時間複雜度為 O(n²)


微信公眾號
覺得本文不錯的話,分享一下給小夥伴吧~

相關文章