題目:某公司有幾萬名員工,請完成乙個時間複雜度為
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。
想明白了這種思路,我們就可以寫出如下**:
1void 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 23using
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 這篇文章來分析一下非比較的線性時間排序方法,計數排序,基數排序,桶排序。正如它的名字,計數排序是通過計算待排序元素小於等於該元素的次數這個屬性,然後利用該屬性將元素以次數為下標挪入另外的陣列,不能...