快速排序(QuickSort)

2021-06-12 12:16:12 字數 2112 閱讀 1157

快速排序(quicksort)也是一種排序演算法,對包含n個陣列的輸入陣列,最壞情況執行時間為o(n^2)。雖然這個最壞情況執行時間比較差,但是快速排序通常是用於排序的最佳實用選擇,這是因為其平均效能相當好,期望的執行時間為o(nlgn),且o(nlgn)中隱含的常數因子很小,另外它還能夠進行就地排序在虛擬環境中也能很好的工作。

快速排序也和合併排序一樣,基於分治法,分為分解、解決、合併三個步驟;

分解:陣列array[low...high]被分為兩個(可能空)子陣列array[low...temp-1]和array[temp+1...high],使得array[low...temp-1]中的每乙個元素都小於等於array[temp],而array[temp+1...high]中的每乙個元素都大於array[temp],下標temp也是在這個過程中被計算出來;

解決:通過遞迴的呼叫快速排序,對子陣列array[low...temp-1],array[temp+1...high]進行排序;

合併:因為兩個子陣列是就地排序的,將他們的合併不需要操作,整個陣列array[low...high]是已經排好序的。

#include #include #include #define n 10

using namespace std;

//快速排序的遞迴演算法

void quicksort(int * array , int low , int high);

//求分割點

int partition(int * array , int low , int high);

//交換兩個變數的值

void exchange(int &a,int &b);

int main()

{ //宣告乙個待排序陣列

int array[n];

//設定隨機化種子,避免每次產生相同的隨機數

快速排序的執行時間與劃分是否對稱有關,而後者又與選擇了哪乙個元素進行劃分有關。如果劃分是對稱的,那麼本演算法在漸近意義上與合併排序一樣快,如果劃分是不對稱的那麼本演算法在漸進意義上與插入排序一樣慢。下面分別討論快速排序的最壞情況劃分、最佳情況劃分、平衡的劃分。

最壞情況劃分:快速排序的最壞情況劃分行為發生在劃分過程中產生的兩個區域分別包含n-1個元素和0個元素的時候。假設演算法每次遞迴呼叫都出現了這種不對稱劃分,劃分的時間代價為o(n),因為對乙個大小為0的陣列進行遞迴呼叫後,返回了t(n)=o(1),故演算法的執行時間可遞迴的表示為:

t(n) = t(n-1) + t(0) + o(n) = t(n-1) + o(n)

從直觀上來看,如果將每一層遞迴的代價加起來,就可以得到乙個算術級數(等式(array,2)其和值的量極為o(n^2))利用代換法可以比較直接的證明遞迴式t(n) = t(n-1) + o(n)的解為 t(n) = o(n^2)。

因此如果在演算法的每一層遞迴上,劃分都是最大程度不對稱的,那麼演算法的執行時間為o(n^2),亦即快速排序演算法的最壞情況執行時間不如插入排序的好。此外當輸入陣列完全排好序時,快速排序的執行時間是o(n^2),而插入排序的執行時間為o(n)。

最佳情況劃分:在partition可能做的最平衡劃分中,得到的兩個子問題的大小都不可能大於[n/2],因為若其中乙個子問題的大小為[n/2],則另外乙個子問題的大小必然為[n/2]-1。在這種情況下,快速排序的執行速度要快得多,這時表達其執行時間的遞迴式為:

t(n) <= 2t(n/2) + o(n)     

解該遞迴式可得t(n) = o(nlgn)。由於在每一層遞迴劃分的兩邊都是對稱的,因此從漸進意義上來看,演算法執行的就更快了。

平衡的劃分:快速排序的平均情況執行時間與其最佳情況執行時間很接近,而不是非常接近與其最壞情況執行時間(證明原因詳細參考《演算法導論》原書第二版p88),因為任何一種按常數比例進行劃分都會產生深度為o(lgn)的遞迴樹,其中每一層的代價都是o(n),因而每當按照常數比例進行劃分時,總的執行時間都是o(nlgn)。

快速排序 QuickSort

快速排序通常用於排序的最佳的使用選擇,其期望執行時間為 o nlgn 能夠進行就地排序。最壞執行時間為 o n 2 演算法描述 分解 divide 陣列 a beg end 被劃分為兩個子陣列 a beg mid 1 和a mid 1 end 使得a beg mid 1 中的資料都小於 a mid ...

快速排序 quicksort

快速排序 quicksort 是分治法的典型例子,它的主要思想是將乙個待排序的陣列以陣列的某乙個元素x為軸,使這個軸的左側元素都比x大,而右側元素都比x小 從大到小排序 然後以這個x在變換後陣列的位置i分為左右兩個子陣列,再分別進行快速排序,直到子陣列中只有乙個元素為止。快速排序演算法如下 void...

快速排序 QuickSort

1,void quicksort int a,int low,int high 這個函式是排序的遞迴部分,mid就是已經確定的基準元素的位置。2,int partition int a,int low,int high 這個函式幹了兩件事 1 挑出來乙個基準元素 這裡選的是最後乙個作為基準 找它的正...