快速排序

簡述

快速排序是屬于交換排序的一種(冒泡排序也是)。是冒泡排序的一種改進。是不穩(wěn)定的一種算法,因為假如出現(xiàn)了同樣的數(shù)字,無法確定同樣的數(shù)字出現(xiàn)的位置是否跟預(yù)測中的一樣。比如,[2, 4, 5, 3, 7, 3],排序后是[2, 3, 3, 4, 5, 7],無法確保第一個3是原來的第一個位置上的3。

時間復(fù)雜度:

平均情況:O(n㏒?n)

最壞情況:O(n2)

最好情況:O(n㏒?n)

空間復(fù)雜度:O(n㏒?n)

快速排序偽代碼

quickSort(A, left, right)
    if right < left
        then
            j = sort(A, left, right);
            quickSort(A, left, j - 1);
            quickSort(A, j-1, right);
end
sort(A, left, right)
    x = a[left];
    i = left;
    j = right;
    while (i < j)
        do 
            while (j > i and A[j]  >= x)
            do 
                j--
            A[i] = A[j];
            while (i < j and A[i] <= x)
            do
                i++
            A[j] = A[i];
    A[j] = x;
    return j;

算法的關(guān)鍵點在于,設(shè)置基準數(shù)(x),然后在一定范圍內(nèi),將范圍正確劃分為小于基準數(shù),基準數(shù),大于基準數(shù),這三部分,然后當范圍足夠小的時候,就是一個正確的排序的集合了。

const arr = [2, 5, 3, 8, 1, 7, 4, 9, 6, 0];

const quickSort = (arr) => {
  const sort = (arr, left, right) => {
    if (left >= right) {
      return
    }
    let i = left, j = right;
    let base = arr[i];
    console.log(arr);
    while(i < j) {
      while ( j > i && arr[j] >= base) {
        j--;
      }
      arr[i] = arr[j];
      while (i < j && arr[i] <= base) {
        i++;
      }
      arr[j] = arr[i];
    }
    arr[j] = base;
    sort(arr, left, j-1);
    sort(arr, j+1, right);
  };
  let newArr = arr.slice();
  sort(newArr, 0, newArr.length - 1)
};
quickSort(arr);

我們來分析一下:

while(i < j) 第一次循環(huán),i = 0,j = 9, base = 2

//arr
[2, 5, 3, 8, 1, 7, 4, 9, 6, 0]

// while( j > i && arr[j] >= base),結(jié)果是
[0, 5, 3, 8, 1, 7, 4, 9, 6, 0]
// arr[j]的結(jié)果賦予arr[i],i = 0, j = 9, base = 2

// while (i < j && arr[i] <= base),結(jié)果是
[0, 5, 3, 8, 1, 7, 4, 9, 6, 5]
// arr[i]的結(jié)果賦予arr[j], i = 1, j = 9, base = 2

while(i < j) 第二次循環(huán),i = 1,j = 9, base = 2

// 上一次結(jié)果的arr
[0, 5, 3, 8, 1, 7, 4, 9, 6, 5]

// while( j > i && arr[j] >= base),結(jié)果是
[0, 1, 3, 8, 1, 7, 4, 9, 6, 5]
// arr[j]的結(jié)果賦予arr[i], i = 1, j = 4, base = 2

// while (i < j && arr[i] <= base),結(jié)果是
[0, 1, 3, 8, 3, 7, 4, 9, 6, 5]
// arr[i]的結(jié)果賦予arr[j], i = 2, j = 4, base = 2

while(i < j) 第三次循環(huán),i = 2,j = 4, base = 2

// 上一次結(jié)果的arr
[0, 1, 3, 8, 3, 7, 4, 9, 6, 5]

// while( j > i && arr[j] >= base),結(jié)果是
[0, 1, 3, 8, 3, 7, 4, 9, 6, 5]
// arr[j]的結(jié)果賦予arr[i], i = 2, j = 2, base = 2

// while (i < j && arr[i] <= base),結(jié)果是
[0, 1, 3, 8, 3, 7, 4, 9, 6, 5]
// arr[i]的結(jié)果賦予arr[j], i = 2, j = 2, base = 2

// i > j 條件不成立, while(i < j) 循環(huán)結(jié)束
// 將arr[j]的值恢復(fù)為基準值,arr[j] = base
[0, 1, 2, 8, 3, 7, 4, 9, 6, 5]

所以第一次sort執(zhí)行完畢,已經(jīng)得到了已2為基準值的符合條件(小于基準值,基準值,大于基準值)的數(shù)組了,只需要將基準值左邊跟基準值右邊也遞歸一下,就能得到有序的數(shù)組了。判斷結(jié)束的條件是left >= right。

如果基準值選到最小值,那么相當于一個長度為數(shù)組長度的冒泡排序操作,如果每一次都選到最小值,那么它的時間復(fù)雜度相當于冒泡排序,其實也就是冒泡排序,因為始終沒有成功地進行分治,也就相當于總是整體地排序。同理,選到最大值也是一樣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 春之既來萬物興,夏雖酷暑雨水頻。 秋至驕陽倉廩足,冬臨寒風(fēng)暖壁爐。 幼嬰頻頻哭不停,老嫗喋喋語不休。 佳人相伴蜜語...
    霎予需閱讀 279評論 0 2
  • 現(xiàn)在是一個信息高速發(fā)展、技術(shù)不斷變革創(chuàng)新的時代。 時代的特性決定我們必須保持持續(xù)創(chuàng)新,才能繼續(xù)走下去,否則只能被顛...
    潤實閱讀 1,973評論 0 1
  • 選擇有意義的一天戴上紫色手環(huán) 感恩曉寧姐給我們創(chuàng)造這個機會,帶領(lǐng)大家一起學(xué)習(xí),讓我們共同練習(xí)不抱怨世界。 當消息發(fā)...
    6190b9a0cbca閱讀 869評論 2 2

友情鏈接更多精彩內(nèi)容