1. 程式人生 > >快速排序的分析及c語言程式碼

快速排序的分析及c語言程式碼

快速排序(Quicksort)是對氣泡排序的一種改進。它的基本思想是:通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。

設要排序的陣列是A[0]……A[N-1],首先任意選取一個數據(通常選用陣列的第一個數)作為關鍵資料,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排序。值得注意的是,快速排序不是一種穩定的排序演算法,也就是說,多個相同的值的相對位置也許會在演算法結束時產生變動。

一趟快速排序的演算法是:

1)設定兩個變數ij,排序開始的時候:i=0j=N-1

2)以第一個陣列元素作為關鍵資料,賦值給key,即key=A[0];

3)從j開始向前搜尋,即由後開始向前搜尋(j--),找到第一個小於key的值A[j],將A[j]和A[i]互換;

4)從i開始向後搜尋,即由前開始向後搜尋(i++),找到第一個大於keyA[i],將A[i]和A[j]互換;

5)重複第34步,直到i=j;(3,4步中,沒找到符合條件的值,即3A[j]不小於key,4A[i]不大於key的時候改變ji的值,使得j=j-1i=i+1,直至找到為止。找到符合條件的值,進行交換的時候i j指標位置不變。另外,i==j

這一過程一定正好是i+j-完成的時候,此時令迴圈結束)。

示例

假設使用者輸入瞭如下陣列:

下標012 34 5

資料627 38 9

建立變數i=0(指向第一個資料), j=5(指向最後一個數據), k=6(賦值為第一個資料的值)。

我們要把所有比k小的數移動到k的左面,所以我們可以開始尋找比6小的數,從j開始,從右往左找,不斷遞減變數j的值,我們找到第一個下標3的資料比6小,於是把資料3移到下標0的位置,把下標0的資料6移到下標3,完成第一次比較:

下標012 34 5

資料327 68 9

i=0 j=3 k=6

接著,開始第二次比較,這次要變成找比k大的了,而且要從前往後找了。遞加變數i

,發現下標2的資料是第一個比k大的,於是用下標2的資料7j指向的下標3的資料的6做交換,資料狀態變成下表:

下標012 34 5

資料326 78 9

i=2 j=3 k=6

稱上面兩次比較為一個迴圈。

接著,再遞減變數j,不斷重複進行上面的迴圈比較。

在本例中,我們進行一次迴圈,就發現ij“碰頭”了:他們都指向了下標2。於是,第一遍比較結束。得到結果如下,凡是k(=6)左邊的數都比它小,凡是k右邊的數都比它大:

下標012 34 5

資料326 78 9 

如果ij沒有碰頭的話,就遞加i找大的,還沒有,就再遞減j找小的,如此反覆,不斷迴圈。注意判斷和尋找是同時進行的。

然後,對k兩邊的資料,再分組分別進行上述的過程,直到不能再分組為止。

注意:第一遍快速排序不會直接得到最終結果,只會把比k大和比k小的數分到k的兩邊。為了得到最後結果,需要再次對下標2兩邊的陣列分別執行此步驟,然後再分解陣列,直到陣列不能再分解為止(只有一個數據),才能得到正確結果。

C語言程式碼如下:

#include <stdio.h>
void Q_sort(int a[],int num);
static int m=0,n=0;

int main() {

    int k = 0;
    int a[9] = {3,6,5,9,7,1,8,2,4};
    printf("原陣列:");
    for (k=0; k<9; k++) {
        printf("%d,",a[k]);
    }
    printf("\n");
    Q_sort(a, 9);
    printf("排序後的陣列:");
    for (k=0; k<9; k++) {
        printf("%d,",a[k]);
    }
    printf("\n比較次數為%d\n 交換次數為:%d\n",m,n);
    
    
    
    return 0;
}

void Q_sort(int a[],int num){
    int i = 0;
    int j = num - 1;
    int k = a[0];
    if (num>1) {//重複的判斷條件,如果長度小於2,則不需排序
        while (i != j) {
            for (; i<j; j--) {
                m++;
                if (a[j]<k) {
                    a[i] = a[j];
                    n++;
                    break;
                }
            }
            for (; i<j; i++) {
                m++;
                if (a[i]>k) {
                    a[j] = a[i];
                    n++;
                    break;
                }
            }
            a[i] = k;
        }
        
        Q_sort(a, i);
        Q_sort(a+i+1, num-i-1);
    }
   
}

用mac終端執行效果如下: