雜湊表之數學原理

2021-05-22 11:12:47 字數 2024 閱讀 8117

.net程式設計師,大多數時候是不需要數學的。因為,有了.net, 資料結構和演算法的重要性被弱化了,作業系統相關的東西被強化了。程式設計師只要求管理好**,而不是設計好演算法。

計算機,我只學會了技術,所以很多問題我都感覺似是而非,感覺實在學習乙個api,而不是在學一門科學。

最近要實現乙個雜湊表,我查詢了很多雜湊函式,高下難分。而且,網上有很多人做了實驗,但是,資料很居然是矛盾的。於是我在想,有沒有一種理想的最優函式,這樣的函式的效率是多少。我的函式,只要接近於這個值就可以了。這樣的理想函式的分析,就必須理解計算機的科學部分,這個是電腦科學永恆的部分。

首先,是乙個很簡單的也是很實用的問題:

「給乙個url 做乙個hash 值,通過這個hash 值,查詢這個url 是否已經在資料庫中存在了,我相信很多人都做過這個問題,很多人採用把乙個url 轉換成乙個無符號的int 型別,然後通過這個int 型別進行查詢。現在的問題是,如果我的**有1000萬個url,會有多少個url 是發生雜湊衝突呢,也就是說,url鏈結不一樣,但是對映成了相同的雜湊值。」有多少衝突,讀完這篇文章你也就會算了。

這個陣列的長度為m,所以會有m個鍊錶,現在的問題是,我有n個key,並且假設 n < m 。問:

沒有元素的鍊錶有多少個

只有乙個元素的鍊錶有多少個

有兩個元素的鍊錶有多少個

這個問題雖然不是很複雜,但是,還是要稍微的轉換一下,動一點點的腦筋。

看問題本身,好像是乙個組合學的問題,就是有m個位置,n個元素往裡面放。從這個角度可以做,但是,比較麻煩。考慮這樣乙個問題, 任意乙個元素,在某個位置不出現,出現一次,出現兩次... 出現n 次的概率。你會發現,這個其實就是上面的鍊錶元素個數的問題。這裡,假設元素都是一樣的,位置也都是一樣的。

這就是乙個binary 分布的問題。不懂的可以看概率論的書本。

這樣,鍊錶有k 個元素的概率分布函式如下:

p = 1 / m

f[k] = (c[n,k]  * p^k * (1-p)^n-k );

現在我假設 m = 2^14, n = 10000

可以求出概率分布如下:

可以看出,大概54%的鍊錶是空的,大概33%的鍊錶有乙個元素,10%左右的鍊錶有兩個元素。如果,你的雜湊函式寫的好,基本上,要接近上面的數字。如果超過了這個數字,雜湊函式也會有問題。這個我已經通過實驗證明了這一點。可能在接下來的章節中介紹我實現的雜湊表。

當然,設計雜湊表,最重要的是要求其平均查詢長度最小。

所有乙個元素的鍊錶包含的元素數目為 m * f[1] * 1, 查詢這些元素的次數為: m * f[1] * 1 * 1

兩個元素的鍊錶包含的元素數目為  m * f[2] * 2,查詢這些元素的次數為: m * f[2] * 2 * 2

這樣平均查詢長度就是:(這裡的平均,實際上不是平均,而是考慮最壞的查詢情況,比如鍊錶長度為2,平均是1.5次,最壞是2次)

求:如果,看到這個式子,還不會求和的話,那麼你趕快回去看看概率論了。

求出的結果是:

l = 1 + (n-1)/ m

是不是非常簡單。

如果n 足夠大,比如上萬了,那麼1就可以忽略了

l = 1 + n / m

這個公式表明,平均查詢長度只和 n / m 的比例有關。如果 m > n 那麼,理想情況下,不會出現平均查詢長度大於2的情況。而,對於100萬的資料的平衡二叉樹,那麼需要20次的查詢,效能是10倍。當然,雜湊表非常的的浪費記憶體。

還有乙個比較簡單的方法,可以簡單的估計大概的數目,那就是平均查詢長度。這裡估計的時候,有乙個假設,就是,在一次查詢時,只有兩種情況,一種是查詢一次,一種是查詢兩次找到。二項分布在m,n相差比較大的時候,隨著k的上公升,概率下降會非常的快,一般重複3次的就很少了,上面的假設是合理的。這樣的話,出現重複的概率就是 n/m 了(可以很簡單的推導出來),0.0023,也就是10000個鏈結裡面,就會有23個重複。如果要求比較高的話,基本上,不能採用這樣的雜湊方法。當然,如果是100萬的話,那10000個鏈結,只有2個重複,基本上是合理的。不過,最好只有10萬。這樣衝突概率就相當的低了。

接下來的文章,我可能會寫雜湊表的實現的一些技巧,如何管理記憶體,如何分配雜湊表的長度(根據不同的需求)。

飛鴿傳書談雜湊表之數學原理

net程式設計師,大多數時候是不需要數學的。因為,有了.net,資料結構和演算法的重要性被弱化了,作業系統相關的東西被強化了。程式設計師只要求管理好 而不是設計好演算法。計算機,我只學會了技術,所以很多問題我都感覺似是而非,感覺實在學習乙個api,而不是在學一門科學。最近要實現乙個雜湊表,我查詢了很...

RSA 數學原理

提起rsa大家一定不陌生,在開發中經常使用,也經常聽同事說道。話說很久以前,人們就懂的了加密這個技術。在戰爭時期,間諜就會拿著密文和密匙來對資訊就行傳遞。這種簡單的密文 密匙 key 就是對稱加密 加密 明文 密匙 解密 密文 密匙 由於這種加密方式過於簡單,所以後來引入了數學演算法。rsa就是由特...

數學,原理,方法,技巧

學校裡學到的東西為什麼沒有用處?主要是學到的東西大部份都有人去實現了。比如資料結構中學做乙個二叉樹。其實在外邊幹活的時候根本不需要。誰會讓你去編寫乙個二叉樹?即使做專案的時候真的有用,大概也有已經實現的類代替了。所以有人說學校裡學到的東西基本沒有用。不過也難怪,因為這些人只是學到了原理或者方法。學校...