排序 計數排序

2021-07-31 09:55:13 字數 2674 閱讀 8378

計數排序假設n個輸入元素中的每乙個都是在0到k區間內的乙個整數,其中k為某個整數。當k = o(n)時,排序的執行時間為θ(n)。

計數排序的基本思想是:對每乙個輸入元素x,確定小於x的元素個數。利用這一資訊,就可以直接把x放到它在輸出陣列中的位置上了。例如,如果有17個元素小於x,則x就應該在第18個輸出位置上。當有幾個元素相同時,這一方案要略做修改。因為不能把它們放在同乙個輸出位置上。

在計數排序演算法的**中,假設輸入是乙個陣列[1..n],a.length = n。我們還需要兩個陣列:b[1..n]存放排序的輸出,c[0..k]提供臨時儲存空間。

counting-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]包含陣列a[i]的元素的個數

for i = 1

to k

c[i] = c[i] + c[i - 1]

//c[i]現在包含陣列a[i]中小於或等於a[i]的元素個數

for j = a.length downto 1

b[c[a[j]]] = a[j]

c[a[j]] = c[a[j]] - 1

圖8-2圖示了計數排序的執行過程。在第2~3行for迴圈的初始化操作之後,陣列c的值全被置為0;第4~5行的for迴圈遍歷每乙個輸入元素。如果乙個輸入元素的值為i,就將c[i]值加1。於是,在第5行執行完後,c[i]中儲存的就是等於i的元素的個數,其中i = 0, 1,…, k。第7~8行通過加總計算確定對每乙個i = 0, 1, …, k, 有多個輸入元素是小於或等於i的。

最後,在第10~12行的for迴圈部分,把每個元素a[j]放到它在輸出陣列b中的正確位置上。如果所有n個元素都是互異的,那麼當第一次執行第10行時,對每個a[j]值來說,c[a[j]]就是a[j]在輸出陣列中的最終正確位置。這是因為共有c[a[j]]個元素小於或等於a[j]。因為所有的元素可能並不都是互異的,所以,我們每將乙個值a[j]放入陣列b中以後,都要將c[a[j]]的值減1。這樣,當遇到下乙個值等於a[j]的輸入元素(如果存在)時,該元素可以被放到輸出陣列中a[j]的前乙個位置上。

計數排序的時間代價是多少呢?第2~3行的for迴圈所花時間為θ(k),第4~5行的for迴圈所花時間為θ(n),第7~8行的for迴圈所花時間為θ(k),第10~12行的for迴圈所花時間為θ(n)。這樣,總的時間代價就是θ(k + n)。在實際工作中,當k = o(n),我們一般會採用計數排序,這時的執行時間為θ(n)

計數排序的乙個重要性質就是它是穩定的:具有相同值的元素在輸出陣列中的相對次序與它們在輸入陣列中的相對次序相同。也就是說,對兩個相同的數來說,在輸入陣列中先出現的數,在輸出陣列中也位於前面。通常,這種穩定性只有當進行排序的資料還附帶衛星資料時才比較重要。計數排序的穩定性很重要的另乙個原因是:計數排序經常會被用作基數排序演算法的乙個子過程。我們將在下一節中看到,為了使基數排序正確執行,計數排序必須是穩定的。

8.2-1參照圖8-2的方法,說明counting-sort在陣列a = 上的操作過程

答:

(a) a =

c =

(b) c =

(c) b =

c =

(d) b =

c =

...(e)

b =

8.2-2證明counting-sort是穩定的。

8.2-3 假設我們在counting-sort的第10行迴圈開始部分,將**改寫為:10.for j=1 to a.length 試證明該演算法仍然正確,它還穩定嗎?

8.2-4 設計乙個演算法,它能夠對於任何給定的駕馭0到k之間的n個整數先進行預處理,然後再o(1)時間內回答輸入的n個整數中有多少個落在區間[a..b]內你設計的演算法預處理時間應為θ(n+k).

與演算法導論裡不同的是a, b的起始下標為0

public

class countingsort

for(int i = 1; i < c.length; i++)

for(int j = a.length - 1; j >= 0; j--)

system.out.println(arrays.tostring(b));

}public

static

void

main(string args) ;

int b = new

int[8];

sort(a,b,9);}}

演算法導論8.2計數排序

排序 計數排序

資料結構和演算法系列目錄 不斷更新 計數排序是一種線性時間的排序,它的時間複雜程度為o n 雖然是線性的時間複雜程度,但是它的空間複雜程度比較高,而且用之前需要有乙個硬性的前提。這個前提在後面給出,這裡先來簡單介紹一下計數排序。計數排序是先掃瞄一邊待排序陣列,並用乙個輔助陣列記錄待排序每個元素應該在...

python計數排序 Python 計數排序

1.python coding utf 8 def counting sort a,b,k 計數排序,偽碼如下 counting sort a,b,k 1 for i 0 to k 初始化儲存區的值 2 do c i 0 3 for j 1 to length a 為各值計數 4 do c a j ...

排序11 計數排序

這裡再介紹一種排序演算法,該方法也是不需要進行元素間的比較,卻能實現排序過程的。不過,與基數排序一樣,它所處理的序列也有些限制 序列元素必須為非負整數,且大小有上限。仍以序列 49 38 65 97 76 13 27 49為例。計數排序的思想在於 首先,求取該序列中最大的元素,顯然為97。然後,建立...