3結論
最近看到了雜湊表的問題,網上也看到了一些解釋,不過並沒有講的很清楚,正好順便來**一下,如有不足之處,還請指出。
最簡單的雜湊演算法可以用取模運算,模一般設定為素數,雖然很多書上講使用素數能夠減小衝突,但是並沒有講為什麼會減小衝突,下面通過幾個例項來說明一下。
選取模為6,7
6為合數,有因子1,2,3,67為素數,有因子1,7
我們看到,合數除了1與本身,還有其他的因子,所以我們考慮使用不同的因子來構造數列。
看到這裡,我們可以做這樣的乙個假設,取模運算的衝突與因子相關,但是具體是如何相關呢,我們後面來實際驗證一下,首先驗證一下與因子相關;
數列1(因子2): 上面我們根據6,7的因子,取了5個數列,數列1與數列2取因子2,分別用奇偶數表示,用來驗證因子與取模運算是否是相關的; 1,3,5,7,9,11,13,15,17
數列2(因子2):
2,4,6,8,10,12,14,16,18
數列3(因子3):
1,4,7,10,13,16,19,22,25,28
數列4(因子6):
1,7,13,19,25,31,37,43,49
數列5(因子7):
1,8,15,22,29,36,43,50,57
然後再取後面的3個數列,驗證另乙個假設,數列的分布以因子為間隔。
數列1 => 取模6 上面我們通過取模運算,發現如果待存資料如果是以2為間隔的話,那麼取模6就會有很多衝突,分布不均勻,0,2,4都沒有儲存,1,3,5衝突很多;餘數01
2345
雜湊表135
雜湊表7911
雜湊表13
1517
2是6的因子,數列1產生了衝突
數列1 => 取模7 然後通過將模取為7,發現同樣的數列1,這時候衝突減少,並且分布均勻,因為我們取的是奇數列,再使用偶數列驗證是否是這樣;餘數01
2345
6雜湊表71
93115
13雜湊表
1517
192不是7的因子,數列1分布均勻
數列2 => 取模6餘數01
2345
雜湊表624
雜湊表12810
雜湊表18
1416
2為6的因子,分布不均勻
數列2 => 取模7餘數01
2345
6雜湊表148
210412
6雜湊表
1618
2不是7的因子,分布均勻
通過上面的取模運算,我們發現,因子確實會影響數列的衝突,並且衝突的間隔就是因子大小,下面再通過其他數列,看一下是否是這樣;
數列3 => 取模6餘數01
2345
雜湊表1
4雜湊表710
雜湊表13
16雜湊表
1922
雜湊表25
283是6的因子,分布不均勻
數列3 => 取模7餘數01
2345
6雜湊表71
1610419
13雜湊表
2822
253不是7的因子,分布均勻
數列4 => 取模6餘數01
2345
雜湊表1
雜湊表7
雜湊表13
雜湊表19
雜湊表25
雜湊表31
雜湊表37
雜湊表43
雜湊表49
6是6的因子,分布不均勻,分部間隔為6
數列4 => 取模7餘數01
2345
6雜湊表71
3731
2519
13雜湊表
4943
6不是7的因子,分布均勻
數列5 => 取模6餘數01
2345
雜湊表3618
1522
29雜湊表
4350
577不是6的因子,分布均勻
數列5 => 取模7 根據上面的結果,我們來分析一般性結論:餘數01
2345
6雜湊表
1雜湊表
8雜湊表
15雜湊表
22雜湊表
29雜湊表
36雜湊表
43雜湊表
50雜湊表
577是7的因子,分布不均勻,分布間隔為7
雜湊表中的分布按照數列的間隔進行分隔,如果數列的間隔恰好整除模,也就是模的因子,那麼就會雜湊表的分布就會產生間隔,恰好是數列的間隔。
由此得到下面的結論:
雜湊表的大小為什麼最好是素數
我也是總結了這篇帖子的主要內容。首先在說明為什麼雜湊表的大小最好為素數之前,先說一下若大小取2的整數冪的問題,對於x mod m這樣的函式,m即為雜湊表的大小,其中的好壞應該取決於x的生成法師和m的值。比如乙個字串 abc 如果把字串當成乙個128進製的整數,寫成 abc 128 128 65 12...
雜湊表取模選擇素數分析
蟬的生命週期為13年或17年,卻很少有14 15或16年,為什麼呢?蟬是弱勢群體,有很多天敵,選擇素數作為其生命週期能最大減少與其天敵們共存的時間,增加自己的存活率,這也是自然選擇的結果。雜湊函式即是將元素對映到對應槽位置的方法。除法雜湊法 h k k mod m 通過取 k 除以 m 的餘數,將關...
雜湊表長度和素數的關係
2長度是否要是素數,能不能是合數,這個問題大家的意見得不到統一。支援用素數的人的理由是,素數可以使得雜湊的分布更加均勻。hash k mix k mod m 雜湊計算中,求餘往往是最後一步,因為沒有機器擁有無限的記憶體,所以必須把結果放入到有限的桶 bucket 中。求餘前的運算,假如混淆 mix ...