1. 程式人生 > >Hash演算法與散列表基礎演算法

Hash演算法與散列表基礎演算法

把一個較大集合P對映到一個較小集合Q中,其中對映演算法位H,即Q=H(P),每一個p對應一個q,一個q可能對應多個p,這就是Hash編碼的初步理解。其中散列表,可以認為是一種特殊的資料結構,有|Q|個所謂的槽,儲存相應的Q值,其中P中的元素出現,就在Q中相對應的結果中進行記錄,對於不同p1,p2對應到同一個槽時,即h(p1)=h(p2)=q1則,q1的槽對應一個list,儲存p1、p2的值。一個好的雜湊函式應該儘可能的將|P|個元素儘可能評價的分為|Q|個槽中。幾個較為經典雜湊演算法如下:
除法雜湊法
其實就是取餘,h(p)=p mod m,其中m小於|Q|的值,但不一定是|Q|的值。使用該方法時,m儘量取一個質數,因為如果m取2或者10的冪,相當於p中的最後幾位起作用,之前的幾位都荒廢了,而m取質數時,所有的元素,都起作用,得到結果可能更為分散。
乘法雜湊法


h(p)=m(pAmod1),其中A的取值是約等於(51)/2=0.618……,而mod 1 就是取小數部分,距離說明p=123456,而|P|是0-232之間的數,而|Q|是0-214之間的數,m即為214,將A取成與(51)/2最為接近的如s/232的數,p*s=76300232+17612864,其中小數部分為17612864/232,該數乘以m,即為17612864/23214,然後取整編碼為67。
全域雜湊
如果雜湊演算法確定,對於某一個hash值q可能對應多個p,即集合Pq,使P_{q}中的p來測試系統,則Hash表起作用的只有q對應的那一個連結串列,從而起不到作用。而如果設計一個雜湊函式簇,在執行時,隨機選擇一個雜湊函式,這樣對應一個p,不同的演算法,得到不同的q,因此就對於該系統就無法確定一個集合P
q
,來攻擊系統。但是當系統實際執行時,一單隨機選擇了雜湊演算法,則就不會改變,一直使用該演算法去初始化Hash表,去檢索系統。
說白了,就是如果演算法固定,就可以得到集合Pq;而全域雜湊的演算法中存在隨機數,這樣會導致,無法得到Pq,但是系統執行時,一旦隨機選擇了雜湊函式,就一直使用該演算法執行。而我們無法知道該系統選擇的函式。使用《演算法導論》中的例子說明,即為:
ha,b(p)=((ap+b)modt)modm
其中,t是一個預先設定的數,其中對於P中的所有元素,都落在[0,t-1]之間,m是編碼集合Q的個數,zp表示集合{0,1,……,t-1},zp表示集合{1,……,t-1}。a和b是分別屬於z
p
zp的隨機數,這樣不同的a,b選擇就構成一個函式簇。