《數據結構與算法分析》讀書筆記——hash表

數據結構:哈希表

1. 散列表 / 哈希表 (hash table) 的實現叫做散列 (hashing)。

2. 理想的散列表是一個包含關鍵字(key)的具有固定大小(TableSize, 0~TableSize-1,數組中就是下標)的數組。

3. 關鍵字到下標的映射,叫做散列函數/哈希函數 (hash function)。

4. 裝填因子(load factor):散列表中元素的個數與散列表大小的比值。


衝突(collision)解決辦法:

1. 分離鏈接法(separate chaining)(數組+鏈表):散列到同一下標的元素建立一個鏈表。裝填因子 ≈ 1

2. 開放定址法 (open addressing hashing):

哈希函數 hi(X) = (Hash(X) + F(i)) modTableSize , 且F(0) = 0

函數F是衝突解決函數,i 表示第 i 次衝突。一般,裝填因子應該低於0.5

    線性探測法 :F是 i 的線性函數。典型:F(i) = i。  缺點:產生一次聚集(primary clustering)。即使表相對較空,也可能某些位置形成區塊。

    平方探測法:F是 i 的二次函數。典型:F(i) = i2。解決一次聚集問題。缺點:產生二次聚集(secondary clustering)。散列到同一位置的那些元素將探測到相同的備選單元。

    雙散列 (double hashing):F是哈希函數。典型:F(i) = i · hash2(X) 。hash2(X) = X – (X mod R),R爲小於TableSize 的素數(儘量避免hash2(X)爲0)。同時,表的大小也儘量爲素數,保證所有的單元都能被探測到;否則備選單元可能提前用完

    

參考: http://www.cppblog.com/guogangj/archive/2009/10/15/98699.html 

斐波那契(Fibonacci)散列法:

平方散列法的缺點是顯而易見的,所以我們能不能找出一個理想的乘數,而不是拿value本身當作乘數呢?答案是肯定的。

   1,對於16位整數而言,這個乘數是40503
2,對於32位整數而言,這個乘數是2654435769
3,對於64位整數而言,這個乘數是11400714819323198485

這幾個“理想乘數”是如何得出來的呢?這跟一個法則有關,叫黃金分割法則,而描述黃金分割法則的最經典表達式無疑就是著名的斐波那契數列,如果你還有興趣,就到網上查找一下“斐波那契數列”等關鍵字,我數學水平有限,不知道怎麼描述清楚爲什麼,另外斐波那契數列的值居然和太陽系八大行星的軌道半徑的比例出奇吻合,很神奇,對麼?

對我們常見的32位整數而言,公式:
index = (value * 2654435769) >> 28


表的元素太滿時,操作時間變長,插入可能失敗。此時可以:

再散列:建立另外一個大約兩倍大的表(而且使用一個相關的新的散列函數),掃描整個原始散列表,計算每個元素的新散列值並將其插入到新表中。表的大小通常是原表大小兩倍後的第一個素數。整個操作叫做再散列(rehashing)


關於哈希表的題目:參考Julyhttp://blog.csdn.net/v_july_v/article/details/6256463


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章