演算法導論之散列表

來源:互聯網
上載者:User
文章目錄
  • 除法散列方法
  • 一個經典的哈系函數
  • 開放定址法
散列方法

哈系表有 m 個槽,如何將關鍵字 key 散列到哈系表的槽中呢?

除法散列方法散列結果由下列散列函數決定:

hash(key)  mod m

其中 m 是 hash 表的大小,注意 m 的選擇:

(1) m 不應是 2 的冪。原因分析如下:

     散列的發散程度取決於 hash(key)  mod m 的分布範圍,

     假設 m = 2^p,  對 m 取餘,結果等於哈系值中二進位的最低 p 位,

     如果雜湊值最低 p 位的排列很相似,則 hash(key)  mod m 的分布

     範圍很小,關鍵字的發散程度就不夠好。

(2) 經驗表明, 取 m 為與 2 的整數冪不太接近的素數。

      可以選擇與 [ 2^p + 2^(p+1) ] /2 最接近的一個素數。

一個經典的哈系函數

不斷地乘以 33, 至於為什麼選擇 33, 還沒足夠充分的解釋,經驗所得。

unsigned long hash(unsigned char *str){    unsigned long value = 5381;    unsigned char *p;    for (p = str; *p; p++) {        value = (value << 5) + value + *p;    }    return value;}

處理衝突的方法 連結法

把散列到同一槽中的所有元素都放在一個鏈表中。如果 hash 表有 n 個元素,m 個槽。

則一個鏈中平均儲存的元素數,即裝載因子 a = n/m ,連結法中裝載因子可能大於 1。

最壞情況下,n 個元素都散列到同一個鏈表,這時尋找事件為 O(n)。 

平均情況下,尋找時間為 O(1+a)

開放定址法

所有的元素都存放在散列表裡,尋找一個元素時,計算出該關鍵字對應的槽,從這個槽開始,

按照一定的順序探查所有的表項,直到找到所需的元素為止,開放定址法的裝載因子 a 絕對小於 1。
插入一個元素時,先計算該關鍵字對應的槽,按照一定的順序探查所有表項,直到找到一個空位為止。

在開放定址法中,尋找和插入都要探查很多槽,對每一個關鍵字,都存在一個長度為 m 的探查序列,設為:

< h(k, 0), h(k, 1), ... , h(k, m-1) > 

理想情況下,探查序列有 m! 種,每個關鍵字的探查序列是 < 0, 1, ..., m-1 > 的 m! 中排列中

任意一種的可能性是相同的,這稱為一致散列。但真正的一致散列很難實現,在實踐中,

有三種技術常用來計算開放定址法中的探查序列: 線性探查,二次探查,和雙重探查。

(1) 線性探查

初始探查位置為 t,下一個探查位置為 t+1,再下一個探查 t+2,..., 依次類推,直到 m-1,

然後又卷繞到 0, 1, ..., 直到最後探查槽 t-1。 散列函數為:

h(k, i) = ( h(k) + i ) mod m

線上性探查序列中,一旦確定了初始探查位置,後面的探查位置都固定下來了,

初始探查位置決定了整個序列,而初始探查位置有 m 種,故只有 m 種不同的探查序列。

線性探查方法比較容易實現,但容易出現群集現象,例如: 假設某個時刻,槽 

T[k+1] 到 T[k+i] 都被連續佔用了,如所示:

在這種情況下,下一個插入的關鍵字,只要其計算出來的初始位置位於區間 [ k+1, k+i+1 ] ,

槽 T[k+i+1] 都會被使用,即槽 T[k+i+1] 被佔用的機率為 (i+1)/m。槽 T[k+i+1] 的使用導致

連續佔用槽的序列長度增加,引起下一個槽 T[k+i+2] 被使用的機率變得更大。這樣惡性迴圈

下去。連續被佔用槽的長度不斷增加,尋找和插入時間的探查時間也不斷增加。這被稱為

群集現象。

(2) 二次探查

散列函數為:

h(k, i) = ( h(k) + c1*i + c2* i^2 ) mod m

初始探查位置為 T[ h(k) ], 後續的探查位置在此基礎上加上一個位移,該位移以二次的方式依賴於 i,

二次探查的效果比一次探查好很多,不過與線性探查一樣,初始探查位置決定了整個序列,故只有

 m 種不同的探查序列。這會導致一種程度較輕的群集現象,稱為二次群集。

(3) 雙重散列

雙重散列是開放定址法中最好的探查方法,其散列函數為:

h(k, i) = [ h(k) + i*h'(k) ] mod m

其中 h'(k) 是輔助散列函數。

為了能尋找整個散列表,值 h'(k) 要與表的大小 m 互質(結論的證明要利用數論

的知識),確保這個性質的一種方法是令 m 為一個質數,並讓 h'(k) 總是產生比

m 小的雜湊值。

在雙重散列法中,一旦確定了 h(k) 和 h'(k),則關鍵字 k 的探查序列就確定下來。

所以一個探查序列由 組合< h(k) , h'(k) > 共同決定,對 m 取餘數,h(k) 可以產生 m 種

探查序列, h'(k) 也可以產生 m 種探查序列,所以雙重散列法可以產生 O(m^2) 種

探查序列。比線性探查和二次探查有很大的提高。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.