算法打基礎——HashⅡ: 全域哈希與完美哈希

這一節涉及數學超級多,各類數論知識,各類不明覺厲! 看了幾遍,才勉強看懂一些,因此這前端

篇稍微簡單的介紹着兩種hash table, 省得瞎說說錯了。框架

這一講的主要知識點是:1. 全域哈希及構造    2. 完美哈希 函數

 

1. 全域哈希及構造性能

介紹全域哈希以前,要先討論一下普通哈希的一個缺點。 舉個charles舉得那個例子:若是你測試

和一個競爭對手同時爲一家公司作compiler的symbol table, 公司要求大家代碼共享spa

(o(╯□╰)o),大家作好後公司評判的標準就是 你倆互相提供一些測試樣例,誰的效率高就買誰的。設計

而後,普通哈希的缺點就出來了:對任意的hash函數h,總存在一組keys,使得blog

, 對某個槽i。即我總能夠找到一組鍵值,讓他們都映射到同一個槽裏面,這樣效率博客

就跟離鏈表差很少了數學

解決的思想就是:獨立於鍵值,隨機的選擇hash 函數。這就跟快排中爲避免最差狀況時隨機化

版本差很少。可是選取hash function的全局域是不能亂定的,不然也打不到理想的性能。

 

下面就給出全域哈希的定義:

 

設U是key的全局域, 設\(\mathcal{H}\) 是哈希函數的有限集合,每個都是將U映射到

{0,1,..,m-1},即table的槽內。 若是對全部不等的\(x,y\in U\),有

換句話說,就是對於任意的不相等key的x和y, 從哈希函數集中選擇一個哈希函數,這兩個key

發生衝突的機率是1/m

 

更形象的,當我隨機選一個哈希函數時,就像在上圖區域亂扔一個飛鏢,落在下面紅色區域中

就會發生衝突,這個機率是1/m

 

 

下面給一個定理,說明爲何全域函數就是好的:

 

設h是從哈希函數全域集\(\mathcal{H}\)中隨機選出的函數h. h被用做把任意n個鍵映射到表T的m個

槽中,對給定鍵值x,咱們有:

定理:E[#collision with x]<n/m

Proof: 設\(C_x\)是表示與key x衝突的鍵值數量的隨機變量,設\(c_{xy}\)是指示變量,即

則,\(E[c_{xy}]=1/m\) 且\(C_x=\sum_{y\in T-\{x\}}c_{xy}\),則

 證畢!

這個定理想要說明的是,這種全域哈希的隨機化選擇能夠達到哈希表理想的效果。注意這裏

n/m是之前定義過的load factor

 

如今給出一種構造全域哈希的方法:

首先選擇一個足夠大的質數p,使得全部的鍵值都在0-p-1之間。且設\(Z_p\)表示{0,1,...,p-1},設

\(Z_p^*\)表示{1,2,..,p-1}. 由於槽m的數量少於key的數量,全部m<p.

而後咱們就能夠設計哈希函數了,設任意的\(a\in Z_P^*,b\in Z_p\),而後

\(h_a,b(k)=((ak+b)mod p)mod m\)

全部這樣的哈希函數族爲:

\(\mathcal{H}_{p.m}=\{h_{a,b}:a\in Z_p^*, b\in Z_p\}\)

例如:選定p=17,m=6,\(h_{3,4}(8)=5\). 每一個哈希函數都是將\(Z_p\)映射到\(Z_m\). 咱們還

能夠看到這個哈希函數族共有p(p-1)個哈希函數

針對這種構造方法構造出的是全域哈希函數的證實就略過了,涉及數學知識確實比較多,講很差。

 

 

 2. 完美哈希 

當鍵值是static(即固定不變)的時候,咱們能夠涉及方案使得最差狀況下的查詢性能也很出色,這就是

完美哈希。實際上,不少地方都會用到靜態關鍵字集合。好比一種語言的保留字集合,一張CD-ROM

裏的文件名集合。 而完美哈希能夠在最壞狀況下以O(1)複雜度查找,性能很是出色的。

完美哈希的思想就是採用兩級的框架,每一級上都用全域哈希

完美哈希的結構如上圖。具體來講,第一級和帶鏈表的哈希很是的類似,只是第一級發生衝突後後面接

的不是鏈表,而是一個新的哈希表。後面那個哈希結構,咱們能夠看到前端存儲了一些哈希表的基本

性質:m 哈希表槽數;a,b 全域哈希函數要肯定的兩個值(通常是隨機選而後肯定下來的),後面跟着

哈希表。

 

爲了保證不衝突,每一個二級哈希表的數量是第一級映射到這個槽中元素個數的平方,這樣能夠保證整個

哈希表很是的稀疏。下面給出一個定理,能更清楚的看到設置m=n^2的做用

 

定理:設\(\mathcal{H}\)是一類全域哈希函數,哈希表的槽數m=n^2. 那麼,若是咱們用一個隨機

函數\(h\in\mathcal{H}\)把n個keys映射到表中。衝突次數的指望最可能是1/2.

Proof:根據全域哈希的定義,對任意選出的哈希函數h,表中2個給定keys衝突的機率是1/m,即1/n^2

且總共有\(C_n^2\)可能的鍵值對,那麼衝突次數的指望就是

\(C_n^2\cdot 1/n^2=n(n-1)/2\cdot 1\n^2 < 1/2\)   證畢!

爲了衝突的理解從指望轉換到機率,引入下面這個推論

推論: 完美哈希沒有衝突的機率至少是1/2

Proof: 這裏主要要用到一個不等式Markov's inequality-對任意非負隨機變量X,咱們有

Pr{X≥t}≤E[x]/t

利用這個不等式,讓t=1,便可獲得衝突次數大於1的機率最多爲1/2

 

由於第二層每一個表槽的個數是這個表中元素n^2,可能會感受到這樣存儲空間會很大,實際上,能夠證

明\(E[\sum_{i=0}^{m-1}\Theta(n_i^2)]=\Theta(n)\), 由於證起來蠻複雜,因此我也略過了%>_<%

 

最後,向各位大牛們提個問題,看到了請必定要教我! 怎麼在博客園裏面更美觀的插入大量數學公式

(最好是用latex語法),支持分多行對齊等結構,如今不會,證實公式都沒辦法寫,寫出來也難看。跪謝!

相關文章
相關標籤/搜索