数据结构与算法 / 排序算法(3)
一、桶排序(Bucket sort)
1、原理
將要排序的數據分到幾個有序的桶里,每個桶里的數據再進行排序。桶內的數據排序完畢之后,再把桶里的數據依次取出,組成的序列就是有序的了。
2、原地排序?
屬于原地排序算法。主要看桶內排序是否時原地排序算法,若選擇插入排序,則桶排序就是屬于原地排序,若選擇了快速排序,則不屬于原地排序。
3、穩定性算法?
不屬于穩定性排序算法。因為根據我的代碼實現,桶內數據會申請內存,故空間復雜度為O(n)。
4、時間復雜度
(1)最好情況
桶數量很多,并且數據均勻分布在各個桶內。
假設要排序的數據數量為 n,分配的桶的個數為 m,那么每個桶中的數據的數量為 k = n / m 。桶內采用快速排序算法,根據之前的推到,快排的時間復雜度為O(nlogn),準確說應該是
C是常數。將 k 代入公式中,得到每個桶的排序時間為
將 k 的計算公式帶入上述公式中,得到如下
m 個桶一共需要的時間為
當 m 接近于 n 時,上述公式就變為如下
所以時間復雜度為 O(n) 。
(2)最壞情況
數據只分配到了一個桶,算法退化成快排,時間復雜度為 O(nlogn) 。
5、數據要求
- 要排序的數據要輕松地劃分成 m 個桶,并且桶與桶之間要有天然的大小順序。
- 數據在各個桶內的分布是均勻的。
6、適用場景:外部排序(數據保存在外部磁盤中,數據量比較大,內存有限,無法將數據全部加載到內存中)
假設有10G的訂單數據,如何按照訂單金額從小到大進行排序?
步驟如下:
- 掃描一遍訂單,確定金額的最小值和最大值,假設分別為 1 和 10k 。
- 將訂單金額分成100個桶,編號分別為 01,02,03,……,那么第 1 個桶內的金額為 1 ~ 1000,第 2 個桶內的金額為 1001 ~ 2000,……
- 每個桶內的數據大概為100M,加載到內存中進行快排是沒有問題的,將排序結果按照桶編號依次存入一個固定文件中,那么該文件中最后顯示的結果就是最終的排序結果。
二、計數排序(Counting sort)
1、原理
當要排序的數據 n 非常大時,而數據所處的范圍又較小,比如最小值和最大值分別為 1 和 k ,那么可以把數據分成 k 個桶,每個桶內的數據都是相同的,從而節省了桶內的排序時間。
實際上計數排序是桶排序一種特殊情況,即:對于桶排序,每個桶內的數據需要進行排序,而計數排序的桶內數據都是相同的,不需要排序。
2、原地排序?
不屬于原地排序算法。根據代碼的實現原理,需要使用計數數組,所以空間復雜度為 O(n) 。
3、穩定性算法?
屬于穩定性排序算法。因為在將數據放入桶中時,保持原有數據順序,再復原時按照順序復原可以。
4、時間復雜度
根據算法的實現原理,只需要遍歷一遍數據即可,時間復雜度為 O(n) 。
5、應用栗子
? ? ? ?如何將某省100萬的考生的高考成績從小到大排序?
分數范圍為 0 ~ 900,每一分都有大量考生重合。可以將分數分成 901 個桶,桶內的分數都是相同,只需要遍歷數據, 將數據放入各個桶內即可。
6、適用范圍
- 數據范圍不大,即:數據量要遠大于數據范圍。
- 數據只能給非負整數進行排序
三、基數排序(Radix sort)
1、原理
將待排序的數列中的數拆分成“位”(十進制),對每一位進行穩定性排序(例如計數排序),直到所有的位都排序完成。
2、原地排序?
不屬于原地排序算法。因為各個位排序時使用了線性排序算法。
3、穩定性排序?
屬于穩定性排序。因為針對每一位的操作實際上都是穩定性排序,保證了相同數據的前后位置。
4、時間復雜度
因為對每一位的排序采用計數排序,時間復雜度為 O(n),假設最大的數據所在的位(十進制)總數為 k,則時間復雜度為O(kn),總體來說時間復雜度約等于 O(n) 。
5、應用栗子
如何對 10 萬個手機號碼你進行從小到大排序?
這里可以采用基數排序算法,將所有的手機號碼拆成11個數字,從后向前一次進行計數排序,因為計數排序屬于穩定性 性算法,這就保證了最終的排序結果是正確的。
6、適用范圍
- 可以將待排序的數據拆成“位”來比較,“位”與“位”之間存在遞進關系。
- 每一位的數據范圍不能太大,這樣可以使用線性排序算法來排序,例如計數排序。
四、總結
1、性質
| 算法種類 | 時間復雜度 | 空間復雜度 | 原地排序 | 穩定性排序 |
| 桶排序 | O(n) | O(n) | × | × |
| 計數排序 | O(n) | O(n) | × | × |
| 基數排序 | O(n) | O(n) | × | × |
2、源代碼
Github
?
參考:極客時間《數據結構與算法之美》王爭
這門課真心推薦,內容很經典、栗子很形象,里面還包含了很多面試題目。真是居家旅行必備良藥。
(SAW:Game Over!)
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的数据结构与算法 / 排序算法(3)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cpp 对象模型探索 / 继承关系下的
- 下一篇: Cpp 对象模型探索 / 多重继承虚函数