1,計數排序是一種非基於比較的排序演算法,
1.計數排序是一種非常快捷的穩定性強的排序方法,時間複雜度o(n+k),其中n為要排序的數的個數,k為要排序的數的組大值。計數排序對一定量的整數排序時候的速度非常快,一般快於其他排序演算法。但計數排序侷限性比較大,只限於對整數進行排序。計數排序是消耗空間發雜度來獲取快捷的排序方法,其空間發展度為o(k)同理k為要排序的最大值。
2.計數排序的基本思想為一組數在排序之前先統計這組數中其他數小於這個數的個數,則可以確定這個數的位置。例如要排序的數為 7 4 2 1 5 3 1 5;則比7小的有7個數,所有7應該在排序好的數列的第八位,同理3在第四位,對於重複的數字,1在1位和2位(暫且認為第乙個1比第二個1小),5和1一樣位於6位和7位。
3.計數排序的實現辦法:
首先需要三個陣列,第乙個陣列記錄a要排序的數列大小為n,第二個陣列b要記錄比某個數小的其他數字的個數所以第二個陣列的大小應當為k(數列中最大數的大小),第三個陣列c為記錄排序好了的數列的陣列,大小應當為n。
接著需要確定陣列最大值並確定b陣列的大小。並對每個數由小到大的記錄數列中每個數的出現次數。因為是有小到大通過出現次數可以通過前面的所有數的出現次數來確定比這個數小的數的個數,從而確定其位置。
對於重複的數,每排好乙個數則對其位置數進行減減操作,以此對完成其餘相同的數字進行排位。
經典排序演算法 - 計數排序counting sort
注意與基數排序區分,這是兩個不同的排序
計數排序的過程類似小學選班幹部的過程,如某某人10票,作者9票,那某某人是班長,作者是副班長
大體分兩部分,第一部分是拉選票和投票,第二部分是根據你的票數入桶
看下具體的過程,一共需要三個陣列,分別是待排陣列,票箱陣列,和桶陣列
var unsorted = new int ; //待排陣列
var ballot = new int[unsorted.length]; //票箱陣列
var bucket = new int[unsorted.length]; //桶陣列
最後再看桶陣列,先看待排陣列和票箱陣列
初始狀態,迭代變數i = 0時,待排陣列[i] = 6,票箱陣列[i] = 0,這樣通過迭代變數建立了數字與其桶號(即票數)的聯絡
待排陣列[ 6 2 4 1 5 9 ] i = 0時,可以從待排陣列中取出6
票箱陣列[ 0 0 0 0 0 0 ] 同時可以從票箱陣列裡取出6的票數0,即桶號
拉選票的過程
首先6出列開始拉選票,6的票箱是0號,6對其它所有數字說,誰比我小或與我相等,就給我投票,不然揍你
於是,2 4 1 5 分別給6投票,放入0號票箱,6得四票
待排陣列[ 6 2 4 1 5 9 ]
票箱陣列[ 4 0 0 0 0 0 ]
接下來2開始拉選票,對其它人說,誰比我小,誰投我票,不然弄你!於是1投了一票,其他人比2大不搭理,心想你可真二
於是2從1那得到一票
待排陣列[ 6 2 4 1 5 9 ]
票箱陣列[ 4 1 0 0 0 0 ]
再然後是,
4得到2和1的投票,共計兩票
1得到0票,沒人投他
5得到2,4,1投的三張票
9是最大,得到所有人(自己除外)的投票,共計5票(陣列長度-1票)
投票完畢時的狀態是這樣
待排陣列[ 6 2 4 1 5 9 ]
票箱陣列[ 4 1 2 0 3 5 ]
入桶的過程
投票過程結束,每人都擁有自己的票數,桶陣列說,看好你自己的票數,進入與你票數相等的桶,go
6共計5票,進入5號桶
2得1票,進入1號桶,有幾票就進幾號桶
4兩票,進2號桶,5三票進3號桶,9有5票,進5號桶
待排陣列[ 6 2 4 1 5 9 ]
票箱陣列[ 4 1 2 0 3 5 ]
入桶前 [ 0 1 2 3 4 5 ] //裡邊的數字表示桶編號
入桶後 [1 2 4 5 6 9 ] //1有0票,進的0號桶
排序完畢,順序輸出即可[ 1 2 4 5 6 9]
可以看到,數字越大票數越多,9得到除自己外的所有人的票,5票,票數最多所以9最大,
每個人最多擁有[陣列長度減去自己]張票
1票數最少,所以1是最小的數,
計數排序同時兼有桶排的高效和快排的霸道,
京東筆試題:
1,採用計數排序演算法對陣列a = {1,0,3,1,0,1,1}進行排序,則輔助陣列c的長度值為()
從上面可以很容易看出來:輔助空間為4
2,關於計數排序的敘述中正確的是:cd
a,計數排序是一種基於比較的排序演算法
b,計數演算法是原地排序演算法
c,計數排序的時間複雜度是o(n)
d,計數排序的空間複雜度是o(n)
經典排序演算法 - 基數排序radix sort
原理類似桶排序,這裡總是需要10個桶,多次使用
首先以個位數的值進行裝桶,即個位數為1則放入1號桶,為9則放入9號桶,暫時忽視十位數
例如
待排序陣列[62,14,59,88,16]簡單點五個數字
分配10個桶,桶編號為0-9,以個位數數字為桶編號依次入桶,變成下邊這樣
| 0 | 0 | 62 | 0 | 14 | 0 | 16 | 0 | 88 | 59 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |桶編號
將桶裡的數字順序取出來,
輸出結果:[62,14,16,88,59]
再次入桶,不過這次以十位數的數字為準,進入相應的桶,變成下邊這樣:
由於前邊做了個位數的排序,所以當十位數相等時,個位數字是由小到大的順序入桶的,就是說,入完桶還是有序
| 0 | 14,16 | 0 | 0 | 0 | 59 | 62 | 0 | 88 | 0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |桶編號
因為沒有大過100的數字,沒有百位數,所以到這排序完畢,順序取出即可
最後輸出結果:[14,16,59,62,88]
經典排序演算法 - 桶排序bucket sort
補充說明三點
1,桶排序是穩定的
2,桶排序是常見排序裡最快的一種,比快排還要快…大多數情況下
3,桶排序非常快,但是同時也非常耗空間,基本上是最耗空間的一種排序演算法
我自己的理解哈,可能與網上說的有一些出入,大體都是同樣的原理
無序陣列有個要求,就是成員隸屬於固定
(有限的
)的區間,如範圍為[0-9](考試分數為1-100等)
例如待排數字[6 2 4 1 5 9]
準備10個空桶,最大數個空桶
[6 2 4 1 5 9] 待排陣列
[0 0 0 0 0 0 0 0 0 0] 空桶
[0 1 2 3 4 5 6 7 8 9] 桶編號(實際不存在)
1,順序從待排陣列中取出數字,首先6被取出,然後把6入6號桶,這個過程類似這樣:空桶[ 待排陣列[ 0 ] ] = 待排陣列[ 0 ]
[6 2 4 1 5 9] 待排陣列
[0 0 0 0 0 0 6 0 0 0] 空桶
[0 1 2 3 4 5 6 7 8 9] 桶編號(實際不存在)
2,順序從待排陣列中取出下乙個數字,此時2被取出,將其放入2號桶,是幾就放幾號桶
[6 2 4 1 5 9] 待排陣列
[0 0 2 0 0 0 6 0 0 0] 空桶
[0 1 2 3 4 5 6 7 8 9] 桶編號(實際不存在)
3,4,5,6省略,過程一樣,全部入桶後變成下邊這樣
[6 2 4 1 5 9] 待排陣列
[0 1 2 0 4 5 6 0 0 9] 空桶
[0 1 2 3 4 5 6 7 8 9] 桶編號(實際不存在)
0表示空桶,跳過,順序取出即可:1 2 4 5 6 9
計數排序 桶排序和基數排序
當輸入的元素是 n 個 0 到 k 之間的整數時,它的執行時間是 n k 計數排序不是比較排序,排序的速度快於任何比較排序演算法。由於用來計數的陣列c的長度取決於待排序陣列中資料的範圍 等於待排序陣列的最大值與最小值的差加上1 這使得計數排序對於資料範圍很大的陣列,需要大量時間和記憶體。例如 計數排...
計數排序 桶排序和基數排序
當輸入的元素是 n 個 0 到 k 之間的整數時,它的執行時間是 n k 計數排序不是比較排序,排序的速度快於任何比較排序演算法。由於用來計數的陣列c的長度取決於待排序陣列中資料的範圍 等於待排序陣列的最大值與最小值的差加上1 這使得計數排序對於資料範圍很大的陣列,需要大量時間和記憶體。例如 計數排...
桶排序 計數排序和基數排序
我們把時間複雜度為o n 的排序演算法,稱為線性排序。意思是,排序時間和排序個數成正比。桶排序就是說,我把n個數,分為m個桶,每個桶裡k個數,k n m。桶的大小順序已經定義好了。然後把桶區間裡的數字扔到桶裡。最後進行桶內快速排序。所以桶的時間複雜度是o m k log n m 又因為k n m,所...