快速排序


思路

像合並排序一樣,快速排序是基於分支模式的:

  • 分解:數組A[n]被划分兩個字數組A[0..q-1]和A[q+1..n],使得對於數組A[0..q-1]中的元素都小於A[q], A[q+1..n]中的元素都大於等於A[q]。此時A[q]就得排好序。
  • 解決:通過遞歸調用快速排序,對字數組A[0..q-1]和A[q+1..n]進行排序
  • 合並:因為兩個字數組已經是就地排好序的了,整個數組已經排好序了。

參考代碼

按照以上模式可以寫出程序:

void quickSort(int A[], int beg, int end)
{
    if (A == NULL || beg > end)
        return;
    int part = getPartition(A, beg, end);
    quickSort(A, beg, part-1);
    quickSort(A, part+1, end);
}

關鍵是找出划分元素的位置函數getPartition,程序如下:其中一次運行過程,如下:

int getPartition(int *a, int beg, int end)
{
    if (beg <= end)
    {
        int part = beg;
        for(int i = beg+1; i <= end; ++i)
        {
            if(a[i] <= a[beg])
            {
                swap(a[part+1], a[i]);
                ++part;
            }
        }
        swap(a[beg], a[part]);
        return part;
    }
}

 

圖示

      

最后,數組的最后一個元素找到了自己最終的位置上,把左右分成了兩個相對獨立的數組。

通過圖示可以看出規律

測試

 

#include <iostream>
using namespace std;
int getPartition(int *a, int beg, int end)
{
    if (beg <= end)
    {
        int part = beg;
        for(int i = beg+1; i <= end; ++i)
        {
            if(a[i] <= a[beg])
            {
                swap(a[part+1], a[i]);
                ++part;
            }
        }
        swap(a[beg], a[part]);
        return part;
    }
}

void quickSort(int *a, int beg, int end)
{
    if (a == NULL || beg >= end)
        return;
    int part = getPartition(a, beg, end);
    quickSort(a, beg, part-1);
    quickSort(a, part+1, end);
}

void tranverse(int *a, int len)
{
    for(int i = 0; i < len; ++i)
    {
        cout << a[i] << " ";
    }
    cout << endl;
}
int main()
{
    int a[] = {3, 9, 0, 1, 3, 2, 2, 7};
    int len =  sizeof(a) / sizeof(int);
    tranverse(a, len);
    quickSort(a, 0, len-1);
    tranverse(a, len);
}

 

性能

時間復雜度:就平均性能而言,快速排序是目前被認為是最好的一種內部排序方法。通常認為快速排序在平均情況下的時間復雜度為O(nlogn)。若初始記錄序列按關鍵字有序或基本有序,快速排序將蛻化為冒泡排序,其時間復雜度為O(n2)。

空間復雜度:最壞情況下,若每趟排序之后,樞軸位置均偏向子序列的一端(有序),棧的最大深度為n。如果在一趟划分之后比較分割所得兩部分的長度,且先對長度短的子序列中的記錄進行快速排序,則棧的最大深度可降為O(logn)。

性能改善:在區間選取隨機數,把該數放在應在的位置,可以有效避免最壞情況。如下

RANDOMIZED-PARTITION(A,p,r)
   i = RANDOM(p,r)
   exchange A[r] <->A[j]
   return PARTITION(A,p,r)

穩定性

不穩定

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM