公開課地址:
http://open.163.com/movie/2010/12/3/A/M6UTT5U0I_M6V2TGI3A.html
全域哈希
誕生:
哈希的根本缺陷:對於任意哈希函數而言,都存在一個不好的健集,使得所有的健都會哈希到同一個槽里去,那么如何解決這種情況呢?如何防止對某個鍵集永遠有較差的表現?如何防止競爭對手使用這個鍵集來降低你的性能表現? 一個詞解決這個問題 —— random!
全域哈希的方法就是隨機選擇一個哈希函數H(當然不是每次操作都選擇一個哈希函數,而是構建一個哈希表的時候隨機選一個,選定之后這個哈希表的所有操作都是基於這個哈希函數,這種方法可以防止競爭對手別有用心的設計一個鍵集,同時也能避免某些鍵集永遠會導致較差的性能,如果是,那么重新建一個表就行!)
定義:
設U為鍵的全域,H是哈希的有限集,H里面的每個哈希函數h將集合U映射到哈希表的m個位置上,如果哈希表滿足:對於U里面的兩個值x,y x≠y {h∈H:h(x)=h(y)}=|H|/m,那么H就是全域的。
|H|的意思是指全域哈希函數的個數,那么從里面任意取一個函數h,這個函數把x和y哈希到同一個位置的概率就是1/m,也就是說,這些函數都是均勻函數。
Hash Function Group構造的一個方法如下:
取 m 為素數,取隨機數 A 為 r+1 位 m 進制的數,表示為 <A0,A1,...,Ar> (其中 0 <= Ai <= m-1為隨機選擇),則哈希函數H[A](K) 定義為:
H[A](K) = sum { Ai * Ki | i =0, 1, ... , m-1 } mod m
證明:
定理得證
完全哈希
哈希的基本缺陷,即使構造了全域哈希,還是不一定能解決不好的鍵集輸入的問題,能不能找到一個完美的解決方案呢?
能不能保證在任何情況下查找的復雜度都在Θ(1)呢?而且哈希表還不能太大,必須滿足n=O(m)
現在來做做推理,如果我們要求對於哈希表中任意一個數x,發生碰撞的次數的期望,小於1
在均勻哈希的情況下,對於每一個數來說,碰撞的可能性都是1/m,那么
Cn2*1/m=n(n-1)/2m <1 那么m>n(n-1)/2 也就是說m是n的平方的量級,所以普通的哈希表是不可能完成這種任務的,除非哈希表構造得非常的大。
解決方案是構造一個雙層哈希的結構,哈希表的底層用來存放第二層的入口指針和所用的哈希函數,第二層才是存放數據元素,證明略