歸併排序與快速排序

快速排序

/*************當每次劃分爲 n-1 個元素和 0 個元素時,最壞情況發生*********/

 //方法一
 function quickSort(arr) {
    if (arr.length <= 1) {
     return arr
 }
 let mid = Math.floor(arr.length / 2)
 let leftArr = [];
 let rightArr = [];
 let midArr = arr.splice(mid, 1);

 for (let i = 0; i < arr.length; i++) {

     if (arr[i] < midArr[0]) {
         leftArr.push(arr[i])
     } else {
         rightArr.push(arr[i])
     }
  }

 leftArr = quickSort(leftArr)

 rightArr = quickSort(rightArr)

 return leftArr.concat(midArr, rightArr)
 }
// 方法二
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));  //鏈接左數組、基準數構成的數組、右數組
 }


 arr = quickSort(arr)

歸併排序

 function merge(arr, p, q, r) {
 let leftArr = arr.slice(p, q + 1)
 let rightArr = arr.slice(q + 1, r + 1)

 leftArr.push(Number.POSITIVE_INFINITY)
 rightArr.push(Number.POSITIVE_INFINITY)
 let i = 0;
 let j = 0;
 for (let k = p; k <= r; k++) {

     if (leftArr[i] <= rightArr[j]) {
         arr[k] = leftArr[i]
         i++
     } else {
         arr[k] = rightArr[j]
         j++
     }
 }
 }

 function mergeSort(arr, p, r) {
 if (p < r) {
     let q = Math.floor((p + r) / 2)
     mergeSort(arr, p, q)
     mergeSort(arr, q + 1, r)
     merge(arr, p, q, r)
 }
 }
 mergeSort(arr, 0, arr.length - 1)

歸併排序與快速排序都是分治策略的應用,二者的區別是:

  1. 快速排序生成新的數組而歸併排序是在原有數組上更改
  2. 二者時間複雜度不相同,快速排序最壞情況是 O(n^2)
  3. 二者區別的根本原因是快速排序的劃分是不穩定的,有可能劃分爲 n-1 個元素的子數組和 0 個元素的子數組

平均情況下快速排序的時間複雜度是 Θ(nlgn),最壞情況是 Θ(n2) :

  1. 當劃分產生的兩個子問題分別包含 n-1 和 0 個元素時,最壞情況發生。
    劃分操作的時間複雜度爲 Θ(n),T(0)=Θ(1)
    算法運行時間的遞歸式爲 T(n)=T(n−1)+T(0)+Θ(n)=T(n−1)+Θ(n)
    解爲 T(n)=Θ(n2)

  2. 當劃分產生的兩個子問題分別包含 ⌊n/2⌋ 和 ⌈n/2⌉−1 個元素時,最好情況發生。
    算法運行時間遞歸式爲 T(n)=2T(n/2)+Θ(n)
    解爲 T(n)=Θ(nlgn)

  3. 事實上只要劃分是常數比例的,算法的運行時間總是O(nlgn)。 假設按照 9:1 劃分,每層代價最多爲 cn,遞歸深度爲 log9n/10=Θ(lgn),故排序的總代價爲 O(nlgn)
    平均情況下,比如一次壞的劃分接着一次好的劃分,壞的劃分那一項可以合併到好的劃分裏,統計上來講平均情況下的時間複雜度仍然是Θ(nlgn)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章