淺解前端必須掌握的演算法(二):簡單選擇排序

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

前言

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

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

演算法介紹

打個比方,喜歡短線炒股的朋友,習慣短時間內不斷地買進賣出,通過價差來實現盈利。但是通常如此頻繁操作,即使失誤不多,也會因為操作的手續費和印花稅而獲利較少。另外一種長線炒股的朋友,習慣長時間持有,不斷地觀察和判斷,時機一到便果斷買進或賣出,交易次數少,收益頗豐。

上一節說的氣泡排序就類似於短線炒股,不斷地比較之後進行交換,完成排序。而本節所要講解的簡單選擇排序,類似於長線炒股,雖然也在不斷地觀察比較,但是會在合適的時機進行交換,並且只移動一次就完成相應關鍵字的排序定位工作。這就是選擇排序法的初步思想。

演算法圖示:

簡單選擇排序圖示

具體實現指導: 假設陣列中元素個數為 n,則需要比較 n-1 輪,在第 i(1<=i<=n) 輪時,需要經過 n-i+1 次比較,選出 Unicode 碼最小的元素,並在本輪結束後與第 i 個元素進行交換,當然了,若第 i 個元素本來就是最小的,就不用進行交換了。注:約定第 1 個元素的下標為 0。

具體實現

var swap = function(arr, posl, posr){
  var m = arr[posl];
  arr[posl] = arr[posr];
  arr[posr] = m;
};
var simpleSelect = function(arr){
  var len = arr.length;
  var i, j, min;

  for (i=0; i<len-1; i++) {
    min = i;
    for (j=i+1; j<len; j++) {
      if (arr[min] > arr[j]) {
        // 兩兩比較,將 Unicode 值更小的元素的下標儲存到變數 min 中
        min = j;
      }
    }
    // 交換元素提取到此處,則交換次數將比氣泡排序的少
    if (min !== i) {
      swap(arr, i, min);
    }
  }

  return arr;
};
複製程式碼

複雜度分析

從以上過程來看,簡單選擇排序的最大特點就是交換元素的次數相當少,節約了相應的時間。當然資料量越大的時候,節約的時間約明顯。

分析其時間複雜度發現,無論最好還是最壞的情況,其與氣泡排序的比較次數都是一樣的,最壞情況下,時間複雜度如下:

淺解前端必須掌握的演算法(二):簡單選擇排序

但是對於交換次數而言,當最好的情況下,交換次數為 0,與氣泡排序的相同;最差的情況下,交換次數為 n-1 次,比氣泡排序的 n(n-1)/2 次少了一個數量級。基於比較和交換次數的綜合,可以得知,簡單選擇排序的時間複雜度依然為 O(n²)

儘管簡單選擇排序與氣泡排序的時間複雜度同為 O(n²),但簡單選擇排序在效能上還是略優於氣泡排序的。


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

相關文章