bucket的英文解釋: linux
Hash table lookup operations are often O(n/m) (where n is the number of objects in the table and m is the number of buckets), which is close to O(1), especially when the hash function has spread the hashed objects evenly through the hash table, and there are more hash buckets than objects to be stored. 算法
能夠這樣理解:數組
一個HASH的結果所對應的地址可存放兩個BUCKET。可解決HASH衝突。 數據結構
一個由5個buckets組成的哈希表,裏面有7個元素:函數
linux的hash函數hash_long等,用了golden ratio來計算。由於桶(bits)的數量須要由hash函數和對衝突的指望來決定,那麼對於hash_long這樣的hash函數,咱們怎麼肯定桶的數量呢? 性能
通常狀況下都是本身根據數據特性來考慮使用的 hash 算法,不是千篇一概咬死一個不放。測試
好比存放 IP 地址的 hash table,用一個 65536 的桶就很好,把 IP 的後 16bit 做爲 key。這種方法絕對比 hash_long、jhash 等函數的碰撞率低。 .net
其實就是這個界和性能的折中。我能夠取我問題空間的最大值。這樣確定能保證鍵值分散。可是這樣會浪費不少空間。然而取得過小,又影響查找效率。感受仍是要在試驗中進行測試。並且我的以爲,hash比其餘搜索的數據結構靈活的地方就是它的可定製性。能夠根據具體狀況調整,以達到最優的效果。blog
大體的思路是這樣的:ci
首先哈希桶的個數是固定的,有用戶構建的時候輸入,一旦構建,個數就已經固定;查找的時候首先將key值經過哈希函數獲取哈希值,根據哈希值獲取到對應的哈希桶,而後遍歷哈希桶內的pairs數組獲取;
這兩種實現方法看似比較相似,但也有差別:
基於哈希桶的狀況下,因爲Hash桶容量的限制,因此,有可能發生Hash表填不滿的狀況,也就是,雖然Hash表裏面還有空位,可是新建的表項因爲衝突過多,而不能裝入Hash表中。不過,這樣的實現也有其好處,就是查表的最大開銷是能夠肯定的,由於最多處理的衝突數是肯定的,因此算法的時間複雜度爲O(1)+O(m),其中m爲Hash桶容量。
而另外一種經過鏈表的實現,因爲Hash桶的容量是無限的,所以,只要沒有超出Hash表的最大容量,就可以容納新建的表項。可是,一旦發生了Hash衝突嚴重的狀況,就會形成Hash桶的鏈表過長,大大下降查找效率。在最壞的狀況下,時間複雜度退化爲O(n),其中n爲Hash表的總容量。固然,這種狀況的機率小之又小,幾乎是能夠忽略的。