前言:桶排序在某種意義上來講它並不是乙個排序演算法,它更像乙個策略方案,事實上的排序還是由別的排序演算法完成,它的步驟分為兩部分(1)資料裝「桶」,(2)每個"桶"使用其餘的排序演算法進行排序。 計數排序實際上是桶排序的特例情況,桶排序代表的是一般情況,資料結構字典的實現思想和桶排序的實現思想一致。
演算法原理:
1. 計算資料的最大值max,最小值min。
2.建立資料"桶",數量為len。(為什麼桶的數量為len,當桶的數量等同於元素數量時,效能最佳,下面效能分析給出了原因)
3.遍歷每乙個元素,進行資料裝桶。(使用對映函式計算下表hashkey )
4.對每乙個"桶"使用冒泡。(因為劃分桶之後的資料數量一般是較小所以資料指數效應不高,偏重考慮考慮係數效能,在這裡因為以上文章中說過氣泡排序所以選用氣泡排序,但是需要具體情況具體來處理,在這裡不過多的討論應該使用哪個排序演算法)
5.鏈結每個已排序好的桶,就得到了排序好的資料。
設:排序資料陣列為arr、長度為len、bucketsort為排序入口函式、hashkey為對映函式。
偽碼:
getmaxmin(arr,len)
else if(arr[i]演算法**:
(1)桶數量和資料數量一致:
1.獲取最大最小值:
2.資料裝桶:
3.完成每乙個bucket的排序:(氣泡排序) (在上圖中可以看到,恰好乙個資料放入了乙個bucket中,無需排序,直接連線即可得到最終陣列,這裡就不在給出動畫)
4.連線每乙個bucket排序後的結果,得到最終陣列。
(2)桶數量和資料數量不一致:
1.獲取最大最小值:
2.資料裝桶:
3.完成每乙個bucket的排序:(氣泡排序)
4.連線每乙個bucket排序後的結果,得到最終陣列。
演算法效能:
1.計算資料的最大最小值,這裡需要遍歷整個陣列消耗效能為len。
2.建立乙個二維陣列,這裡的建立空間的效能消耗為len。
3.遍歷每乙個元素,這裡需要遍歷整個陣列消耗的效能為len。
4.對每乙個"桶"使用快速排序,這裡的效能為"桶"中元素數量q,所以效能為q² ,其中q在概率上我們可以認為1,所以效能消耗為1。(在桶排序中,最關鍵的問題是如何定義桶的數量,在一般情況中,可以認為資料是完全隨機的,那麼元素屬在每乙個桶中的概率都是相等的,所以桶的數量等於元素的數量時效能最佳,因為恰好乙個元素可以放乙個桶中,既不多也不少,每乙個桶都無需開展排序演算法,這是非常理想的情況。在一般應用中,我們使用的資料並不是完全隨機的,例如對全國成績的排序,很明顯有幾百萬資料之多,但是成績的可能出現的數字卻遠遠沒有幾百萬這麼多,所以建立幾百萬個桶是沒有意義的,且不現實的)
5.演算法效能為len+len+len+ q²= 3n+1 = o(n)。
結語:1.桶排序實際上是由兩部分構成(1)資料分類、分塊(2)使用具體的排序演算法排序。(實際上裝桶的目的就是為了降低比較排序時n的數量)
2.在計數排序中所使用的對映函式,會讓一樣的數值儲存在一起,而在桶排序中對映函式,會讓同乙個區間內的資料儲存在一起,區間內的數值位置不確定,所以需要在用其他比較排序演算法進行排序,來確定數值的位置。數排序從這種角度講是桶排序的特例,桶排序是一種一般情況。在不一樣的資訊維度上,獲取兩種演算法,實質是對已知資訊的利用率的提公升,在無限集合到有限集合之間處理的差別。 (事實上資訊的定義就是消除不確定,產生確定的事物。在桶排序和計數排序的區別中,實際上就是消除資料種類的不確定,確定了它為整數。在桶排序中,劃分桶是為了確定桶與桶之間的關係,每個桶的比較排序,是為了確定元素之間的關係。 在實際專案中有許多的途徑,能了解許多的資訊,其實都可作為演算法消除不確定的條件)
3.從以上演算法過程中,可以知道,實際上桶的數量和桶中元素的數量是影響桶排序速度的關鍵,事實上也是通過對資訊的一種假定處理得到了乙個線性時間的排序演算法,假定了資料是完全隨機分布的,實際上絕大部分問題中資料並不是隨機分布的,在假定條件不成立的情況下,桶排序會退化,會退化成具體使用的演算法的排序效能。(例如在所有資料都是同乙個數字的情況下,所有的資料都會被裝入乙個桶中,那麼具體的排序演算法,需要排序的資料總量並沒有減少)
4.在實際專案中桶排序中的桶的數量,並不是如演算法中設定的那麼簡單,或者說不會有那麼理想。怎麼讓桶排序更小的概率出現退化現象,或者說讓資訊的假定成功,其實可以從資訊的假定上入手,現在假定的資訊為隨機資料,事實上可以統計資料出現的概率建立函式影象(使用擬合等數學手段)。假定資訊為可以建立函式影象的資料, 那麼就可以根據這個函式來進行桶的建立,當資料比較"密集"時,可以建立更多的桶來裝資料,當資料比較"稀疏"時,則可以少建立桶。歸根結底就是如何保證每個桶中的元素數量盡量相等。
5.桶排序因為用到了假定資訊的型別,事實上是有可能是不成立,因為假定資訊並不是限制資訊,假定可能並不成立,計數排序實際上是限定了資訊,所以並不會有演算法退化的現象。
6.桶排序,可能會發生極端退化情況,例如(使用快速排序的桶排序)處理元素完全相同的資料時,桶排序 -> 快速排序 ->氣泡排序,效能從理想中的n -> log2 -> n^2 一路退化。遺憾的是實際這種問題在實際專案中是經常出現的,也無法完美解決,但其實出現這種情況的時候都是特定資料,有很多種解決方案,讓出現的概率降低,甚至無法遇到,從而解決。總之就是具體的問題需具體分析,沒有最好的演算法,只有最適用的演算法。
ps:附上快速排序、氣泡排序、計數排序。
直擊資訊的本質 計數排序
前言 計數排序,顧名思義它是統計每個元素出現的次數。實際上是通過限定了資訊的範圍,在只適用於整數情況下達到了線性時間效能。整數集合在已知範圍的情況下,整數的個數是有限的,實際上限定資料為整數,是把問題從無限多種情況,變成了有限種情況 演算法原理 1.先計算資料中的最大值max最小值min。找出資料範...
直擊資訊的本質 陣列
後語傳送門 陣列指多個連續的最小儲存單元所構成的集合,且每個單元只可被乙個陣列使用。陣列會記錄起始最小儲存單元的下標 start 與陣列長度 len 在計算機系統中,可以把記憶體看做乙個超大的陣列 實際上陣列是由,最小儲存單元這個概念規定自然產生的一種資料結構,即多個連續的最小儲存單元稱之為陣列。實...
直擊資訊的本質 鍊錶
資料基本操作 後語傳送門 鍊錶指多個不連續的最小儲存單元所構成的集合。鍊錶會記錄起始最小儲存單元的下標 start 與結束最小儲存單元的下標 end 鍊錶解決了陣列的增刪缺陷,同時能提高總空間利用率,但同時也帶來了查詢開銷的增大的問題。下圖中w,q,e為陣列 e為鍊錶。鍊錶實際上是通過記錄元素之間的...