八大排序——快速排序

作爲一個學後臺的同學,如果你不會希爾排序,我可以認爲你學的不夠,但如果你不會快速排序,那麼我就要偷偷笑你了。快速排序算法最早由圖靈獎的獲得者Tony Hoare設計出來,更牛逼的是,這個算法被列爲了20世紀十大算法之一。對,沒錯,是十大算法,不是十大排序算法,這足以看出這個排序算法在學界中大牛心目中的地位,我們這些程序猿還有什麼理由不去學習它?不說玩笑話,下面讓我們真正的體會一下快速排序。

快速排序算法

快速排序(Quick Sort),其基本思想爲:在序列中選出一個元素作爲“樞紐”,經過一趟排序將序列分割成兩部分,其中一部分均比“樞紐”元素小,另一部分均比“樞紐”元素大,然後把這兩部分作爲新的序列執行同樣的操作,直到元素數無法進行分割爲止。細心的同學會發現,整個操作其實是一個遞歸調用,排序會將“樞紐”元素放置到合適的位置(合適的位置意味着它的位置不需再改變),而其它元素都會放置到合適的區域(注意的說的是合適的區域),而分割的作用就是使被放到合適位置的元素越來越多,合適的區域越來越精確,直到合適的區域精確到成爲一個位置爲止(仔細體會)。小二,上代碼:

#include <stdio.h>

void sort(int a[], int left, int right)
{
    if(left >= right)//如果left大於或者等於right就代表已經整理完成一個部分了
    {
        return;
    }
    int i = left;
    int j = right;
    int key = a[left];//取下標爲left的元素爲“樞紐”元素,並將其賦值給key

    while(i < j)//當i和j"相遇"的時候,說明所有元素都被比較了一遍,這時候就不用再循環
    {
        while(i < j && key <= a[j])
        {
            j--;//向前尋找
        }

        a[i] = a[j];//數值覆蓋
        while(i < j && key >= a[i])
        {
            i++;//向後尋找
        }
        a[j] = a[i];//數值覆蓋
    }

    a[i] = key;//將“樞紐”元素放在合適的位置
    sort(a, left, i - 1);//用同樣的方式對分出來的左邊的小組進行同上的做法
    sort(a, i + 1, right);//用同樣的方式對分出來的右邊的小組進行同上的做法
}
void main()
{
    int a[]={5,6,1,4,9,2,9};
    int i;
    int length=sizeof(a)/sizeof(int);
    sort(a,0,length-1);
    for(i=0;i<length;i++){
        printf("%d\t",a[i]);
    }
    printf("\n");
}

光看代碼很難理解其中的變換過程,下表是第一次排序的數值變化,大家可以體會一下:
這裏寫圖片描述
其中標黃色的部分爲被變化的值,從圖中也解答了大家對20和25行代碼註釋的一個疑問(即數值覆蓋會不會造成數據丟失),大家可以看到,第一次覆蓋,其實是“樞紐”元素被覆蓋,而我們已經提前將“樞紐”元素賦給了key,而其後的數值覆蓋覆蓋的都是冗餘的值,因爲我們每覆蓋一次都沒有將之前位置的值清空,那麼它就是冗餘的,覆蓋它不會造成數據丟失。
注:快速排序的時間複雜度爲O(nlogn)。

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