快速排序時間複雜度 簡明分析(平均/最壞/with high probabilty)

最近研究隨機算法,發現快速排序作爲一種入門算法,分析其時間複雜度還是很有趣的。

首先,證明其最壞時間複雜度爲O(n^2) 是很容易的。證明其平均時間複雜度的期望是O(n\lg n)也有很多不同方式。這裏介紹兩種簡單的方式。

需要說明的是,這裏的快排是隨機化的排序算法。因此對於任意輸入,其期望的時間複雜度都是相同的。

首先是比較容易的方式。我們假設算法的輸入是有序序列<a1,a2,a3,a4...,an>的一個排列。也就是說,我們將這個排好序的序列打亂順序之後作爲輸入。算法的時間複雜度就是需要進行比較的次數。注意到一下結論:

  1. 任意兩個元素至多隻可能比較一次。因爲比較操作是在partition時候進行的。每次比較,就說明其中一個數字是被選擇作爲pivot。所以,在之後的排序中,都不會再涉及pivot。
  2. 兩個元素會被排序的可能性與兩個元素之間包含的元素個數有關。爲了解釋這一點,我舉兩個例子。
    1. 首先,考慮<a1,a2>這兩個最小的元素。它們之間會進行比較的概率是1。爲什麼呢。因爲每次選取pivot的時候,如果沒有選中<a1,a2>這兩個元素中的某個的時候,那它們一定會被扔到pivot的同一側。這樣,這兩個元素在同一個區間裏面,接下來仍然有可能被比較。如果選中了<a1,a2>,那麼由於它們在同一個區間裏面,因此它們一定會比較。
    2. 其次,考慮a1和an。也就是最小的元素和最大的元素。它們比較的概率是2/n。因爲考慮第一次選取pivot的時候。如果選中了a1和an這兩個元素中的某一個,那麼它們一定會比較。這樣的概率是2/n。而第一次沒有選取a1和an其中的某一個時,pivot一定會將這兩個元素分別放在不同的遞歸區間裏面,這樣它們就不可能再被比較了。

通過第二點,我們很容易想到這個結論:<ai、aj>這兩個元素被比較的概率是2/(j-i+1)。爲什麼呢。因爲排好序的序列中考慮這麼一段數字<ai,ai+1,...,aj>。當選取pivot不在這個區間裏面時,這段數字依然在同一個區間,也就是說接下來它們仍然有可能被比較。而當某次選取pivot在這段數字裏面的時候。如果沒有選<ai、aj>,那麼接下來這兩個數字就被放到不同區間了,不會被比較,概率是(j-i+1-2)/(j-i+1)。而選中其中一個元素,它們一定被比較,概率就是2/(j-i+1)。

所以,得到這個結論之後,一切就很簡單了。用基本概率論的知識就行了。定義一個隨機變量Xij,爲1就說明ai和aj進行了比較,否則爲0。那我們要求的就是\sum X_{ij}。由Linearity of expectation,E[\sum X_{ij}]=\sum E[X_{ij}]。Xij是01變量,期望就是1/j-i+1.

 

因此期望的時間複雜度就是 \sum_{i=1}^{n-1} \sum_{j=i+1}^n 1/(j-i+1) = \sum_{i=1}^{n-1} \sum_{h=1}^{n-i} 1/h。再根據調和級數就知道,時間複雜度爲O(nlog n)。

 

其實還有一種更簡單的方法,從概率模型出發。以後再說吧。

 

此外,還可以證明with high probabilty,時間複雜度不會超過 c*nlog n。這也是類似的方法。以後有機會再說。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章