O n 時間的排序 計數排序

2022-09-02 06:27:14 字數 1814 閱讀 1686

題目:某公司有幾萬名員工,請完成乙個時間複雜度為

o(n)

的演算法對該公司員工的年齡作排序,可使用

o(1)

的輔助空間。

分析:排序是面試時經常被提及的一類題目,我們也熟悉其中很多種演算法,諸如插入排序、歸併排序、氣泡排序,快速排序等等。這些排序的演算法,要麼是

o(n2)

的,要麼是

o(nlogn)

的。可是這道題竟然要求是

o(n)

的,這裡面到底有什麼玄機呢?

題目特別強調是對乙個公司的員工的年齡作排序。員工的數目雖然有幾萬人,但這幾萬員工的年齡卻只有幾十種可能。上班早的人一般也要等到將近二十歲才上班,一般人再晚到了六七十歲也不得不退休。

由於年齡總共只有幾十種可能,我們可以很方便地統計出每乙個年齡裡有多少名員工。舉個簡單的例子,假設總共有

5個員工,他們的年齡分別是25、

24、26、

24、25。我們統計出他們的年齡,

24歲的有兩個,

25歲的也有兩個,

26歲的乙個。那麼我們根據年齡排序的結果就是:24、

24、25、

25、26,即在表示年齡的陣列裡寫出兩個

24、兩個

25和乙個26。

想明白了這種思路,我們就可以寫出如下**:

1

void sortages(int ages, int

length)236

3738

39int index = 0;40

41for(int i = 0; i <= oldestage; ++i)

425354}

5556 }

在上面的**中,允許的範圍是0到

99歲。陣列

timesofage

用來統計每個年齡出現的次數。某個年齡出現了多少次,就在陣列

ages

裡設定幾次該年齡。這樣就相當於給陣列

ages

排序了。該方法用長度

100的整數陣列輔助空間換來了

o(n)

的時間效率。由於不管對多少人的年齡作排序,輔助陣列的長度是固定的

100個整數,因此它的空間複雜度是個常數,即

o(1)

。以上**何海濤部落格

《演算法導論》中文版第八章第二節 計數排序 裡面有關於這個演算法的詳細講解。根據演算法導論所說,計數排序的乙個重要特性就是它的穩定性,上面的演算法似乎沒有體現出來。根據《演算法導論》,我用c++實現了書上的例子。

1 #include 2

3using

namespace

std;45

void countingsort(int ages, int len, int

out, int

range)613

14for(int i=0;ii)

1518

19for(int i=1;i<=range;++i)

2023

24for (int i=len-1;i>=0;--i)

252930}

3132

intmain()33;

37int b[8

];38

39 countingsort(a,8

,b,age_range);

4041

for(int i=0;i<8;i++)

4245

46 cout <4748 system("

pause");

4950

return0;

51 }

極客時間 排序 計數排序

計數排序只能用在資料範圍不大的場景中,如果資料範圍 k 比要排序的資料 n 大很多,就不適合用計數排序了。而且,計數排序只能給非負整數排序,如果要排序的資料是其他型別的,要將其在不改變相對大小的情況下,轉化為非負整數。比如,還是拿考生這個例子。如果考生成績精確到小數後一位,我們就需要將所有的分數都先...

計數排序(線性時間排序) 演算法導論

之前的排序都是通過比較得到的,即比較排序 在排序的最終結果中,各元素的次序依賴與它們之間的比較。而時間複雜度最好的也是o nlgn 接下來說乙個未經比較的排序,而複雜度則是線性的。計數排序 假設n個輸入元素的每乙個都是在0 k區間內的乙個整數,其中k為某個整數。當k o n 時,排序的執行時間為o ...

線性時間排序 計數排序 基數排序 桶排序

之前總結的都是通過比較方法進行排序的演算法,我們知道,通過比較排序演算法平均時間複雜度最多為o lgn 這篇文章來分析一下非比較的線性時間排序方法,計數排序,基數排序,桶排序。正如它的名字,計數排序是通過計算待排序元素小於等於該元素的次數這個屬性,然後利用該屬性將元素以次數為下標挪入另外的陣列,不能...