快速排序對於初學者而言算是實現較為困難的一種排序方法,而其**的實現方法也有多種,本文採用其中一種方法實現快排,並採用主定理對其複雜度進行分析。
對於乙個已經排序好的陣列,一定有該特性:任取乙個數字,其左邊的數字(若存在)全部小於該數字,其右邊的數字(若存在)一定大於該數字。
那麼我們便可以對乙個未排序陣列,任取乙個數字(中心數),將小於它的放左邊,大於它的放右邊,這樣就實現了基本的第一步排序。
然後我們對左右兩邊分別重複以上步驟,直到陣列徹底排序。
在快速排序演算法中比較重要的乙個步驟是找到中心數,一般而言,乙個隨機的中心數可以使演算法更為高效,但為了簡便,我們一般取最後乙個數字作為中心數。
import data
nums = data.get_data(
1000
)def
quick_sort
(nums, l, r)
:if l < r:
m = partition(nums, l, r)
quick_sort(nums, l, m)
quick_sort(nums, m +
1, r)
# 將陣列進行初步劃分,小於中心點放左邊,大於放右邊,返回中心數
defpartition
(nums, l, r)
: m = r -
1# 取最後乙個數作為中心數
i = l # i左邊的元素均小於中心數,初始沒有
for j in
range
(i, m)
:if nums[j]
<= nums[m]
: nums[i]
, nums[j]
= nums[j]
, nums[i]
i +=
1 nums[i]
, nums[m]
= nums[m]
, nums[i]
# 將中心數歸位
return i
quick_sort(nums,0,
len(nums)
)print
(nums)
主定理主定理最早出現在《演算法導論》中,提供了分治方法帶來的遞迴表示式的漸近複雜度分析。
規模為n的問題通過分治,得到a個規模為n/b的問題,每次遞迴帶來的額外計算為f(n^d)。
即複雜度的表示式可表示為以下形式:
t(n) = at(n/b) + f(n^d)
那麼就可以得到問題的複雜度為:
1、t(n) = o(n^d log(n)), if a = b^d
2、t(n) = o(n^d ), if a < b^d
3、t(n) = o(n^logb(a))), if a > b^d
主定理的證明以及應用舉例可參考這篇博文:主定理的證明及應用舉例
快速排序演算法,我們使用的遞迴實現,便可用主定理加以分析。
每次問題劃分為兩個問題,規模減半,帶來一次額外的迴圈,a=2,b=2,d=1,滿足上述第一種情況,那麼複雜度為n^2 log(n)。
遞迴時間複雜度分析 主定理分析
標籤 演算法 複雜度分析 以下是評估遞迴時間複雜度的主定理,例如有遞迴形式 t n at n b f n 其中,a 1 和 b 1 均為常數,f n 是乙個確定的正函式。在 f n 的三類情況下,我們有 t n 的漸近估計式 若對於某常數 0 有 f n o n 則 t n theta n 若 f ...
演算法複雜度分析 主定理
規模為n的問題通過分治,得到a個規模為n b的問題,每次遞迴帶來的額外計算為c n d t n at n b c n d 那麼就可以得到問題的複雜度為 可見,每次遞迴把問題分為a個規模為n b的子問題。從根節點開始,共有logb n 1層,葉子節點數為a logb n 那麼,第j層共有aj個子問題,...
快速排序演算法分析
快速排序演算法 include include void quicksort int arr,int nleft,int nright i nleft j nright int nmid nleft nright 2 int nmidval arr nmid while i j from right...