為什麼一般hashtable的桶數會取乙個素數
設有乙個雜湊函式
h( c ) = c % n;
當n取乙個合數時,最簡單的例子是取2^n,比如說取2^3=8,這時候
h( 11100(二進位制) ) = h( 28 ) = 4
h( 10100(二進位制) ) = h( 20 )= 4
這時候c的二進位制第4位(從右向左數)就」失效」了,也就是說,無論第c的4位取什麼值,都會導致h( c )的值一樣.這時候c的第四位就根本不參與h( c )的運算,這樣h( c )就無法完整地反映c的特性,增大了導致衝突的機率.
取其他合數時,都會不同程度的導致c的某些位」失效」,從而在一些常見應用中導致衝突.
但是取質數,基本可以保證c的每一位都參與h( c )的運算,從而在常見應用中減小衝突機率..
(個人意見:有時候不取質數效率也不會太差..但是無疑取質數之比較保險的..)
以上就是我的理解
補充一點,這裡是說在常見應用中,往往有些資料會比較相近,這時候用質數比較好,比如要存放的資料是壓縮的狀態,比如儲存乙個描述當前搜尋狀態的表,的這時候雜湊不用質數衝突機率就比較大。
如果是隨機分布的整數,那麼雜湊模數只要取到足夠大,在概率上來說都是一樣的,但是這顯然脫離實際應用。
你說的情況 是比較特殊的,因為選取了比較小的乙個質數,當選去大質數n時,就可以僅在n進製的某一位失效,結合計算機系統的特性,n進製位表示法往往是不關鍵的,而常用的2^n進製比較關鍵,所以可以避免衝突。
其實,偶用一些大數做過測試,用來存放乙個壓縮為二進位制的鄰接矩陣,當模數足夠大時,即便是合數也能有很接近質數的效果,但在某些(幾十個)合數上會造成效率嚴重下降,所以質數是比較保險的。
你不妨自己做實驗,不要去選隨機整數,而要考慮一些常見應用,用質數和合數進行測試,主要考察平均裝載因子,你得到的結論可能和我一樣:合數絕大多數時候效果也不錯,但在一部分合數上效果差得出奇,而質數幾乎全部都有很好的效果。
我個人認為更普遍意義的理解,如果不取素數的話是會有一定危險的,危險出現在當假設所選非素數m=x*y,如果需要hash的key正好跟這個約數x存在關係就慘了,最壞情況假設都為x的倍數,那麼可以想象hash的結果為:1~y,而不是1~m。但是如果選桶的大小為素數是不會有這個問題。
為什麼一般hashtable的桶數會取乙個素數
為什麼一般hashtable的桶數會取乙個素數 設有乙個雜湊函式 h c c n 當n取乙個合數時,最簡單的例子是取2 n,比如說取2 3 8,這時候 h 11100 二進位制 h 28 4 h 10100 二進位制 h 20 4 這時候c的二進位制第4位 從右向左數 就 失效 了,也就是說,無論第...
盤盈的存貨一般應作為什麼處理
企業進行存貨清查盤點,應當編制 存貨盤存報告單 並將其作為存貨清查的原始憑證。經過存貨盤存記錄的實存數與存貨的賬面記錄核對,若賬面存貨小於實際存貨,為存貨的盤盈 反之,為存貨的盤虧。對於盤盈 盤虧的存貨要記入 待處理財產損溢 科目,查明原因進行處理。企業在財產清查中盤盈的存貨,根據 存貨盤存報告單 ...
一般人為什麼不成功? 陳安之
一般人為什麼不成功?陳安之 在研究如何成功致富之前,我們一定要了解,一般人為什麼會失敗。一般人都在研究成功者如何成功時,卻從來沒有思考過失敗者為何失敗,所以也就沒有避免失敗者所犯的錯誤。我以前每天都在研究成功者如何成功,卻從未研究失敗者如何失敗。失敗是成功之母,檢討是成功之父。我發現,如果你沒做成功...