第 8 章 線性時間排序

  到目前爲止,我們已經介紹了幾種能在O(nlgn)時間內排序的n個數的算法。歸併排序和堆排序達到了最壞情況下的上界;快速排序在平均情況下達到上界。這些算法都有一個性質:在排序的最終結果中,個元素的次序依賴於它們之間的比較。稱這些排序算法爲比較排序
  8.1節證明對包含n個元素的輸入序列來說,任何比較排序在最壞情況下都要經過Ω(nlgn)次比較。因此,歸併排序和堆排序是漸近最優的,並且任何已知的比較排序最多就是在常數因子上由於它們。
  8.2、8.3、8.4節討論三種線性時間複雜度的排序算法:計數排序、基數排序和桶排序。

8.1 排序算法的下界

定理8.1 在最壞情況下,任何比較排序算法都需要做Ω(nlgn)次比較。
推論8.2 堆排序和歸併排序都是漸近最優的比較排序算法。

8.2 計數排序

計數排序假設n個輸入元素中的每一個都是在0到k區間內的一個整數,其中k爲某個整數。當k=O(n)時,排序的運行時間爲θ(n)。
  計數排序的基本思想:對每一個輸入元素x,確定小於x的元素個數。利用這一信息,就可以直接把x放到它輸出數組中的位置上了。
  在計數排序算法中,假設輸入是一個數組A[1..n],A.length=n。還需要兩個數組:B[1..n]存放排序的輸出,C[0..k]提供臨時存儲空間。
COUNTNG-SORT(A, B, k)

let C[0..k] be a new array
for i = 0 to k
    C[i] = 0
for j = 1 to A.length
    C[A[j]] = C[A[j]] + 1
//C[i]now contains the number of elements equal to i
for i = 1 to k

    C[i] = C[i] + C[i-1]
//C[i]now contains the number of elements less than or equal to i
for j = A.length downto 1
    B[C[A[j]]] = A[j]
    C[A[j]] = C[A[j]]-1

計數排序的總的時間代價是θ(k+n)。在實際工作中,當k = O(n),一般採用計數排序,這使得運行時間爲θ(n)。
  計數排序的一個重要性質就是它是穩定的:具有相同值的元素在輸出數組中的相對次序與它們在輸入數組中的相對次序相同。也就是說,對兩個相同的數,在輸入數組中先出現的數,在輸出數組中也位於前面。計數排序的穩定性很重要的另一個原因是:計數排序經常會被用作基數排序算法的一個子過程。

8.3 基數排序

基數排序是一種用在卡片排序機上的算法。
基數排序算法是非常直觀的。在下面的代碼中,我們假設n個d位的元素存放在數組A中,其中第 1 位是最低位,第 d 位是最高位
RADIX-SORT(A,d)

for i = 1 to d
    use a stable sort to sort array A on digit i

引理8.3 給定n個d位數,其中一個數位有k個可能的取值。如果RADIX-SORT使用的穩定排序方法耗時θ(n+k),那麼他就可以在θ(d(n+k))時間內將這些數排好序。
當d爲常數且k=O(n)時,基數排序具有線性的時間代價。
引理8.4 給定一個b位數和任何正整數r<=b,如果RADIX-SORT使用的穩定排序算法對數據取值區間是0到k的輸入進行排序耗時θ(n+k),那麼它就可以在θ((b/r)(n+2r ))時間內將這些數排好序。
利用計數排序作爲中間穩定排序的基數排序不是原址排序。當主存的容量比較寶貴時,更傾向於想快速排序這樣的原址排序。

8.4 桶排序

  桶排序假設輸入數據服從均勻分佈,平均情況下它的時間代價是O(n)。與計數排序類似,因爲對輸入數據作了某種假設,桶排序的速度也很快。具體來說,計數排序假設輸入數據都屬於一個小區間內的整數,而桶排序則假設輸入是由一個隨機過程產生,該過程將元素均勻、獨立地分佈在[0, 1)區間上。
  桶排序將[0,1)區間劃分爲n個相同大小的子區間,或稱爲。然後,將n個輸入數分別放到各個桶中。因爲輸入數據是均勻的、獨立地分佈在[0, 1)區間上,所以一般不會出現很多數落在同一個桶中的情況。爲了得到輸出結果,我們先對每個桶中的數進行排序,然後遍歷每個桶,按照次序把各個桶中的元素列出來即可。
  在桶排序的代碼中,我們假設輸入是一個包含n個元素的數組A,且每個元素A[i]滿足0<=A[i]<=1.此外,算法還有一個臨時數組B[0..n-1]來存放鏈表(即桶),並假設存在一種用於維護這些鏈表的機制。
BUCKET-SORT(A)

n = A.length
let B[0..n-1] be a new array
for i = 0 to n-1
    make B[i] an empty list
for i = 1 to n
    insert A[i] into list B[⌊nA[i]⌋]
for i = 0 to n-1
    sort list B[i] with insertion sort
concatenate the list B[0],B[1], ... , B[n-1] together in order

桶排序的期望運行時間爲:θ(n)。即使輸入數據不服從均勻分佈,桶排序也仍然可以線性時間內完成。只要輸入數據滿足下列性質:所有桶的大小的平方和與總的元素數呈線性關係,那麼桶排序任然能在線性時間內完成。

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