算法:基於比較的排序算法


最近整理了常用的排序算法,整理好,留下自己的思考過程。

1、冒泡排序:

(1)平均時間復雜度:O(n2)

(2)最好時間復雜度:O(n)

(3)最壞時間復雜度:O(n2)

(5)空間復雜度:O(1)

(5)穩定性:穩定

(6)JavaScript實現:

function bubble ( arr ) {
    var len = arr.length;
    var tmp;
    //  外層循環負責控制排序的趟數
    for(var i = 0; i < len - 1; i++){
       // 內層循環負責進行一趟排序
       for(var j = 0; j < len - 1 - i; j++){
          if(arr[j + 1] < arr[j]){
              tmp = arr[j];
              arr[j] = arr[j + 1];
              arr[j + 1] = tmp;
          };
       };
    };
    return arr;
};

2、選擇排序:

(1)平均時間復雜度:O(n2)

(2)最好時間復雜度:O(n2)

(3)最壞時間復雜度:O(n2)

(4)空間復雜度:O(1)

(5)穩定性:不穩定

(6)JavaScript實現:

function select( arr ) {
   var len = arr.length;
   // 外層循環需要進行len - 1趟排序
   for(var i = 0; i < len - 1; i++){
      var index = i;
      var min = arr[i];
      var tmp;
      // 內層循環從未排序的數組元素中比較出最小的一個
      for(var j = i + 1; j < len; j++){
         if(min > arr[j]){
            index = j;
            min = arr[j];
         };
      };
      // 將其放在排序后的數組元素的最后
      tmp = arr[i];
      arr[i] = min;
      arr[index] = tmp;
   };
};

3、插入排序:

(1)平均時間復雜度:O(n2)

(2)最好時間復雜度:O(n)

(3)平均時間復雜度:O(n2)

(4)空間復雜度:O(1)

(5)穩定性:穩定

(6)JavaScript實現:

function insert ( arr ) { 
   var len = arr.length;
   var tmp;
   for(var i = 1; i < len; i++){
      // 取出當前的數組元素
      tmp = arr[i];
      for(var j = i - 1; j >= 0; j--){
         if (arr[j] > tmp) {
            arr[j+1] = arr[j];
         } else {
       break;
     }; };
// 插入取出的數組元素 arr[j+1] = tmp; }; return arr; }

 4、希爾排序:

(1)平均時間復雜度:O(nlogn) ~ O(n2)

(2)最好時間復雜度:O(n1.3)

(3)最壞時間復雜度:O(n2)

(4)空間復雜度:O(1)

(5)穩定性:不穩定

(6)JavaScript實現:

// 插入排序
function sort( arr, di ){
   for(var i = di; i < arr.length; i++){
      var guard = arr[i];
      for(var j =i -di; j >= 0 && guard < arr[j]; j -= di){
         arr[j+di] = arr[j];
      };
      arr[j+di] = guard;
   };
   return arr;
}

//  希爾排序,本質上是以不同的步長多次進行插入排序
//  步長的選擇對希爾排序的效率有顯著影響
function shell ( arr ) {
  var di = parseInt( arr.length / 2 );
  while ( di >= 1) {
      arr = sort( arr, di);
      di = parseInt( di / 2 );
  };
  return arr;
};

5、歸並排序:

(1)平均時間復雜度:O(nlogn)

(2)最好時間復雜度:O(nlogn)

(3)最壞時間復雜度:O(nlogn)

(4)空間復雜度:O(n)

(5)穩定性:穩定

(6)JavaScript實現:

// 對被歸並的左右兩個數組進行歸並排序
// 被輸入的左右兩個數組,都是有序的。
function merge (left, right){
   var l = 0,
         r = 0;
   var result = [];
   // 對左右兩個數組的首項,進行比較,較小的推入棧中。
   while(l < left.length && r < right.length){
      if(left[l] < right[r]){
         result.push( left[l] );
         l += 1;
      } else {
         result.push( right[r] );
         r += 1;
      };
   };
   // 經過上面的比較,左右兩個數組,必定有一個數組比較完畢,一個沒有比較完畢。
   // 但是,在不同情況的遞歸層,有不同的表現,故而將二者未比較的元素都連接到result中。
   // 由於,左右兩個數組在輸入前就是有序的,剩余未經比較的數組元素也是有序的,且都大於之前經過比較的數組元素,故而可以將其連接到result。
   // 下方的代碼,實質上是將左右數組中,未經比較的數組元素連接到result。
   result = result.concat( left.slice(l) );
   result = result.concat( right.slice(r) );
   return result;
};

function mergeSort ( arr ){
   var len = arr.length;
   // 結束遞歸
   if(len <= 1){
      return arr;
   };
   // 切割數組,並對切割后的數組進行遞歸操作
   var middle = Math.floor( len/2 );
   var left = mergeSort( arr.slice(0, middle) );
   var right = mergeSort( arr.slice(middle) );
   // 完成遞歸后,進行歸並
   return merge(left, right);
}

6、快速排序:

(1)平均時間復雜度:O(nlogn)

(2)最好時間復雜度:O(nlogn)

(3)最壞時間復雜度:O(n2)

(4)空間復雜度:O(logn) ~ O(n)

(5)穩定性:不穩定

(6)JavaScript實現:

function quick ( arr ) {
   var less = [],
         pivotList = [],
         more = [],
         result = [],
         len = arr.length;
   // 結束遞歸
   if(len <= 1){
       return arr;
   };

   // 與基准對比,將數組划分為小,中,大三組
   var pivot = arr[0];
   for(var i = 0; i <len; i++){
      if(arr[i] < pivot){
         less.push(arr[i]);
      } else if(arr[i] > pivot){
         more.push(arr[i]);
      } else {
         pivotList.push(arr[i]);
      };
   };
   // 遞歸地對划分出的小、大兩個組進行快速排序
   less = quick(less);
   more = quick(more);
   // 將排序好的小,中,大三組連接起來 
   result = result.concat(less, pivotList, more);
   return result;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM