快排分析

xue_發表於2018-10-23
var quickSort = function(arr) {

    if (arr.length <= 1) { return arr; }

        var pivotIndex = Math.floor(arr.length / 2);
        
        var pivot = arr.splice(pivotIndex, 1)[0];
        
        var left = [];
        
        var right = [];

    for (var i = 0; i < arr.length; i++){
    
        if (arr[i] < pivot) {
        
            left.push(arr[i]);
        
        } else {
        
            right.push(arr[i]);
        
        }
    
    }

    return quickSort(left).concat([pivot], quickSort(right));

};
複製程式碼

這是從網上覆制下來的快排。快排是利用到了遞迴,那麼遞迴就是需要考慮空間複雜度。

先看,遞迴是怎麼執行的

{
    code()
    {
        code()
        {   
            code()
            {
                code() 
                // 從最裡面向外執行,而值是從外面一步步分解後傳進來,那麼系統就得儲存好沒一步被操作的值
            }
        }
    }
}
複製程式碼

假設資料是佔用100MB記憶體,那麼運算過程儲存的值也就會是100Mb,當然只會比這個多,就不細算,只要知道這個概念就好。

我們改進一下,直接在原陣列上直接換值,而不用臨時引用型別儲存

 var quickSort = function (arr) {
      let len = arr.length
      
      quickSortInternally(arr, 0, len-1)
      
      // 遞迴
      function quickSortInternally(arr, p, r) {
          if(p>=r)return; // 陣列長度等於1的時候結束遞迴
          let q = partition(arr, p, r)
          quickSortInternally(arr, 0, q-1)
          quickSortInternally(arr, q+1, r)
      }
    
      // 獲取區分點
      function partition(arr, p, r) {
          let i = p;
          let pivot = arr[r] // 區分點
          
          for(let j = i; j < r; j++){
              if(arr[j]<pivot){
                  let tem = arr[j]
                  arr[j] = arr[i]
                  arr[i] = tem
                  ++i
              }
          }
          
          let tem = arr[r]
          arr[r] = arr[i]
          arr[i] = tem
          
          return i;
      }
    }
複製程式碼

快排的最優狀態才是O(nlogn),最壞狀態是O(n2), 歸併排序最好最壞都是O(nlogn),那麼為什麼js中的排序不用歸併排序呢,就是因為歸併不是原地排序,需要額外的記憶體空間。如果快排按照第一個那樣寫,那還是用歸併排序把,因為第一個快排也不是原地排序。

快排的複雜度是看切分的深度,第二個寫的快排區分點是那最後一個做區分點,如果陣列是[1,2,3,4],這種順序完成了或者接近完成的[1,3,2,4,5],這種就會O(n2)的時間複雜度。那麼怎麼解決這種問題。 我們可以取三點然後在取一箇中間值(1,9,6;取6做區分點)。就會解決這種問題,直接嘗試修改一下吧。 當然第二個引數再加一個fun引數,比較陣列不都是[1,2,3]這樣的,很多時候是[{},{},{}]這樣的資料

相關文章