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


這一節涉及數學超級多,各種數論知識,各種不明覺厲! 看了幾遍,才勉強看懂一些,所以這

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

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

 

1. 全域哈希及構造

介紹全域哈希之前,要先討論一下普通哈希的一個缺點。 舉個charles舉得那個例子:如果你

和一個競爭對手同時為一家公司做compiler的symbol table, 公司要求你們代碼共享

(o(╯□╰)o),你們做好后公司評判的標准就是 你倆互相提供一些測試樣例,誰的效率高就買誰的。

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

, 對某個槽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語法),支持分多行對齊等結構,現在不會,證明公式都沒辦法寫,寫出來也難看。跪謝!

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM