計數排序vs基數排序vs桶排序

超人汪小建發表於2019-03-03

從計數排序說起

計數排序是一種非基於元素比較的排序演算法,而是將待排序陣列元素轉化為計數陣列的索引值,從而間接使待排序陣列具有順序性。

計數排序的實現一般有兩種形式:基於輔助陣列和基於桶排序。

基於輔助陣列

整個過程包含三個陣列:待排序陣列A、計數陣列B和輸出陣列C。

簡單來說,就是通過統計待排序陣列A中元素不同值的分佈直方圖,生成計數陣列B,然後計算計數陣列B的字首和(此步操作可以看成計算待排序陣列A中每個元素的位置資訊),最後通過逆序迴圈將元素對應賦值到輸出陣列C中,輸出陣列C即是最終排序結果。

image

image

基於桶排序

其實就是用桶排序來維護穩定性,因為在每個桶中的元素是以佇列結構排序的,可以維護元素的順序。

主要步驟:

  1. 按元素的最大健值與最小健值之差來建立指定數量的桶,並在每個桶中建立一個佇列。
  2. 按順序遍歷待排序陣列,將它們放到對應桶的佇列中。
  3. 按桶編號順序進行遍歷,將每個桶中佇列按順序輸出回原陣列中。

image

image

image

計數排序的不足

可以看到輔助陣列的長度和桶的數量由最大值和最小值決定,假如兩者之差很大,而待排序陣列又很小,那麼就會導致輔助陣列或桶大量浪費。

基數排序

基數排序改善了計數排序,簡單來說,基數排序演算法就是將整數或字串切分成不同的數字或字元,然後按對應位置的數或字元分別進行比較,這樣就能將輔助陣列或桶的數量降低到一個較小的值,經過多輪排序後得到最終的排序結果。

比如下面對於十進位制的數值比較,只需要10個桶即可,但要保證每個桶能放得進所有元素。

image

第一階段:針對個位數將元素放到對應的桶中。

image

第二階段:針對十位數將元素放到對應的桶中。

image

第三階段:針對百位數將元素放到對應的桶中。

image

最終按照桶順序輸出得到排序結果。

image

桶排序

桶排序是改善計數排序的方法之一,其基本思想是將待排序陣列分配到若干個桶內,然後每個桶內再各自進行排序,桶內的排序可以使用不同的演算法,比如插入排序或快速排序,屬於分治法。每個桶執行完排序後,最後依次將每個桶內的有序序列拿出來,即得到完整的排序結果。

待排序陣列的最大元素與最小元素分別為19和1,那麼總的範圍區間可定義為[0,19],假設用4個桶,則桶的區間分別為[0,4][5,9][10,14][15,19]。可以看到桶的數量可以控制在很小的範圍內,而且桶的容量大小可以動態擴充。

image

按照值將元素放到對應桶內。

image

按照桶順序將元素依次輸出得到排序結果。

image

總結

  • 基數排序和桶排序可以看成是計數排序的泛化版本,使用了某些措施優化排序過程。
  • 在桶排序中當桶的個數取最大值(max-min+1)的時候,就變成了計數排序,所以計數排序時桶排序的一種特例。
  • 基數排序可以看做是多輪桶排序,基數排序以有效位的角度,每個有效位都進行一輪桶排序。
  • 當用最大值作為基數時,基數排序就退化成了計數排序。

-------------推薦閱讀------------

我的開源專案彙總(機器&深度學習、NLP、網路IO、AIML、mysql協議、chatbot)

為什麼寫《Tomcat核心設計剖析》

2018彙總資料結構演算法篇

2018彙總機器學習篇

2018彙總Java深度篇

2018彙總自然語言處理篇

2018彙總深度學習篇

2018彙總JDK原始碼篇

2018彙總Java併發核心篇

2018彙總讀書篇


跟我交流,向我提問:

計數排序vs基數排序vs桶排序

歡迎關注:

計數排序vs基數排序vs桶排序

相關文章