排序演算法——快速排序

來源:互聯網
上載者:User

標籤:排序演算法   快速排序   

參考書籍:《資料結構與演算法分析——C語言描述》

快速排序是在實踐中最快的已知排序演算法,它的平均時間複雜度O(NlogN)。當然在最壞的情況下為O(N^2),但稍加努力就可以避免這種情形。

像歸併排序一樣,快速排序也是一種分治的遞迴演算法,可簡單表示如下:


將數組S排序的基本演算法由下列簡單的四步組成。

1、數組元素至少大於或等於4個,否則直接利用插入排序完成。

2、利用特定方法(三數中值分割法)取數組某一特定元素V,稱之為樞紐元。

3、將數組中其他元素(即S-{V})分成兩個不相交的子集。S1={x∈S-{V} | x≤V}和S2={x∈S-{V} | x≥V}。

4、繼而對兩個子集S1和S2進行同理1-3的遞迴運算。


如何選取樞紐元呢?

此處我們介紹是三數中值分割法。選取數組中最左端、最右端和中心位置的三個元素,比較三個元素的大小,並按照小的在左邊交換彼此位置,取中間值作為樞紐元。

例如:

對於初始序列:


left=8;right=0;center=6。

顯然此處樞紐元應為piovt=6;並且此時的排序為:


然後我們選取兩個指標i和j。從序列的首尾兩端出發,除樞紐元外的元素與樞紐元進行比較。此時可把樞紐元6移至right-1的位置(因為right已經比piovt大了,left已經比piovt小了)。

即:


如果i指示的數比樞紐元小,則i++;直至遇到大於等於樞紐元的數停止。

如果j指示的數比樞紐元大,則j++;直至遇到小於等於樞紐元的數停止。

若此時i<j(說明元素沒有全部比完),則交換i和j位置的數。繼續上述的比較,直至i≥j(說明元素全部比完)。

比完時序列如下:

此時在交換位置i的數和樞紐元。如所示:

樞紐元已將原序列分割為兩個子集:

1、大於樞紐元:7,9,8

2、小於樞紐元:0,1,4,2,3,5

同理可以將兩個子集繼續進行如此的分割排序。

代碼實現:

#include<stdio.h>void QuickSort(int *data,int n);void Qsort(int *data,int left,int right);int Median3(int *data,int left,int right);//3數中值分割法取出樞紐元void Swap(int *a,int *b);void InsertSort(int *data,int N);int main(){    int i=0;    int data[8]={34,8,64,51,32,21,9,5};    printf("Before Sort:\n");    for(i=0;i<8;i++)    {        printf("%d\t",data[i]);    }    QuickSort(data,8);    printf("\nAfter Sort:\n");    for(i=0;i<8;i++)    {        printf("%d\t",data[i]);    }    return 0;}void Swap(int *a,int *b){    int tmp;    tmp=*a;    *a=*b;    *b=tmp;}int Median3(int *data,int left,int right){    int center=(left+right)/2;    //確保data[left]<=data[center]<=data[right]    if(data[left]>data[right])        Swap(&data[left],&data[right]);    if(data[left]>data[center])        Swap(&data[left],&data[center]);    if(data[center]>data[right])        Swap(&data[center],&data[right]);    Swap(&data[center],&data[right-1]);    return data[right-1];}void QuickSort(int *data,int n){    Qsort(data,0,n-1);}void Qsort(int *data,int left,int right){    int i,j;    int pivot;    if(left+3<=right)//保證至少有4個數    {        pivot=Median3(data,left,right);        i=left;        j=right-1;        for(;;)        {            while(data[++i]<pivot);            while(data[--j]>pivot);            if(i<j)                Swap(&data[i],&data[j]);            else                break;        }        Swap(&data[i],&data[right-1]);        Qsort(data,left,i-1);        Qsort(data,i+1,right);    }    else        InsertSort(data+left,right-left+1);//調用插入排序}void InsertSort(int *data,int N){    int i=0,j=0;    int tmp=0;    for(i=1;i<N;i++)    {        tmp=data[i];//待插入的值        for(j=i;j>0 && data[j-1]>tmp;j--)//在已排序數組中從後往前遍曆,直到找到插入的位置j            data[j]=data[j-1];        data[j]=tmp;    }}




排序演算法——快速排序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.