void QSort(SqList *L,int low,int high)
{
int pivot;
if(low<high){
pivot=Partition(L,low,high);//返回樞軸,操作次數爲n
QSort(L,low,pivot-1);//對樞軸左邊進行排序
QSort(L,pivot+1,high);//對數軸右邊進行排序
}
}
最好的情況下,樞軸對兩邊的劃分都很均勻,用遞歸樹來表示如下圖:
方法一:
根據代碼我們知道,每一層的遞歸操作次數爲該次遞歸所傳入的元素個數,忽略每次減去的樞軸(1個元素並沒有給到下一層,但是每層這裏減掉一個常數對複雜度的分析影響不大,所以暫時忽略),即:
第1層是n次,
第2層有2次遞歸,每次n/2次,共n次操作,
第3層有4次遞歸,每次n/4次,共n次操作,
……
(最後一層)第k層有k次遞歸,每次n/2^k次,共n次操作
由於遞歸結束的條件是隻有一個元素,所以這裏的n/2^k=1 => k=logn
即遞歸樹的深度爲logn
時間複雜度=每層的操作次數*樹的深度=nlogn 即:O(nlgn);
方法二:
我們用T(n)來表示時間複雜度,有:
解這個遞推公式:
有代入上一個公式有
有代入上一個公式有
...
最後一層遞歸有代入上一個公式有
已知最後一層遞歸時操作次數爲1,,有
帶入公式得
有T(1)=0;
所以 即:O(nlgn);
方法三:
主定理求解遞歸式:
令a>=1和b>1是常數,f(n)是一個函數,T(n)是定義在非負整數上的遞歸式:
,其中n/b爲向上或向下取整。那麼T(n)有如下漸近界:
1、若對某個常數>0,有,則;
2、若,則;
3、若對某個常數>0,有,且對某個常數c<1和所有足夠大的n有,則;
關於以上幾種情況的解釋可以看算法導論第三版P54,這裏稍微解釋一下:
(用來分析算法複雜度的話可以把和O看成是相同的,想要具體瞭解的自行百度或者我後面可能再加進來)
三種情況的每一種我們將函數f(n)與進行比較,這兩個之中的較大解決定了遞歸式的解,大小相當的情況下則乘上一個對數因子
接下來通過這種方法來計算快排的時間複雜度:
遞推公式:
主定理:
所以a=2,b=2,,對應第二種情況,所以
是不是很簡單……
後面再寫平均和最差吧,或者可以看這篇博文