內排序(五)——快速排序

核心思想

快速排序的核心思想如下:
從當前參加排序的元素中任選一個元素(通常稱之爲分界元素)與當前參加排序的那些元素
進行比,凡是小於分界元素的元素都移到分界元素的前面,凡是大於分界元的元素都移到分界元素的後面,分界元素將當前參加排序的元素分成前後兩部分,而分界元素處在排序的最終位置。然後,分別對這兩部分中大小大於1的部分重複上述過程,直到排序結束。

該過程是一個遞歸過程;

分界元素也叫作劃分元素、基準元素、樞軸、軸值、支點等;可以選第一個或者最後一個、或位置居中的那個元素作爲分界元素;

快速排序的每一趟至少可以確定一個元素的最終位置

算法步驟

算法中用到的變量
s:當前參加排序的那些元素的第一個元素在序列中的位置,初始值爲1;
t :當前參加排序的那些元素的最後那個元素在序列中的位置,初始值爲n;
i,j :兩個位置變量,初始值分別爲s 與t+1;
分界元素爲K[s],如下圖:
在這裏插入圖片描述

算法步驟如下:
1、反覆執行動作 i+1 —> i,直到 K[s] <= K[i] 或者 i = t ;
反覆執行動作 j-1—> j,直到 K[s] >= K[j] 或者 j=s;
2、若i < j,則 K[i] 與 K[j] 交換位置,轉到第1步;
3、若i >= j,則 K[s] 與 K[j] 交換位置,到此,分界元素 K[s] 的最終位置已經確定(即爲j),然後對被K[s]分成的兩部分中大小大於1 的部分重複上述過程,直到排序結束。

對於此步驟的理解:i 和 j 可以看做一頭一尾的兩個哨兵,i 哨兵從頭到尾移動,用來發現比分界元素K[s]大的元素,j 哨兵從尾到頭移動,用來發現比分界元素K[s]小的元素,兩個哨兵發現一個交換一個,直到兩個哨兵相遇,相遇點即爲K[s]分界元素的最終位置,這就是一趟快速排序,然後分別對分界元素左右兩邊分別遞歸執行一趟排序。

算法實現

快速排序的C語言遞歸實現如下:

void QUICK(keytype K[ ],int s,int t)
{ 
    int i, j;
    if(s<t){
       i=s;
       j=t+1;
       while(1){
           do i++;
           while(!(K[s]<=K[i] || i==t));
           do j– –;
           while(!(K[s]>=K[j] || j==s));
           if(i<j)
              SWAP(K[i],K[j]);         /*交換K[i]與K[j]的位置*/
           else
              break;
       }
       SWAP(K[s],K[j]);          /*交換K[s]與K[j]的位置*/
       QUICK(K,s,j-1);           /* 對前一部分排序 */
       QUICK(K,j+1,t);           /* 對後一部分排序 */
    }
}

快速排序的主算法如下:

void QSORT(keytype K[],int n)
{
     QUICK(K,1,n);        //第一次調用
}

算法分析

快速排序的時間複雜度爲O(nlog2n)

如果初始序列是順序或者逆序,則快速排序的比較次數爲1+2+3……+ n-1 = n(n-1)/2,此時快速排序淪落爲慢速排序。

爲什麼說快速排序是性能最好的排序算法?

參考文章:爲什麼說快速排序是性能最好的排序算法?

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