查找 - 計算式查找法 - 哈希法

▶ 哈希函數的構造方法

> 數字分析法dom

假設關鍵字 Key 爲 8 位十進制整數:函數

① 肯定哈希表的長度,示例:100,即地址空間爲 0 ~ 99測試

② 肯定 「取值比較均勻分佈」 的位置,示例:第四位和第七位編碼

③ 則哈希函數爲 H(Key) = H(ABCDEFGH) = DGspa

④ 示例: H(81301367) = 0六、 H(81346532) = 43code

> 平方取中法遞歸

假設關鍵字 Key 爲大寫英文字符串:rem

① 肯定哈希表的長度,示例:1000,即地址空間爲 0 ~ 999字符串

② 指定內部編碼,示例: A-01, B-02, C-03 。。。 Z-20hash

③ 計算內部編碼平方,取中間三位做爲哈希值

關鍵字 內部編碼 內部編碼的平方 H(Key)關鍵字的哈希地址
KEKA 11052501 122157 778 355001 778
KYAB 11250102 126564 795 010404 795
AKEY 01110525 001233 265 775625 315

> 分段疊加法

假設關鍵字 Key 爲超長的整數,示例 12360324711202065 :

① 肯定哈希表的長度,示例:1000,即地址空間爲 0 ~ 999

② 從左到右,分割成 N 個三位數,右側不足三位的捨棄,示例:123 603 247 112 020

③ 將 N 個三位數相加,結果超過三位數的左側捨棄,示例:

H(Key) = H(12360324711202065) = 123 + 603 + 247 +112 + 020 = 1105 % 1000 = 105

> 除留餘數法

假設哈希表長 m, p 爲小於等於 m 的最大素數,哈希函數爲:

H(Key) = k % p

示例:key 爲 80, 表長 13,最大素數 13,H(Key) = H(80) = 80 % 13 = 5

> 僞隨機數法

採用一個僞隨機函數做爲哈希函數, 即 H(key) = random(key)

▶ 處理衝突的方法

> 開放定址法(再散列法)

關鍵字 key 的初始哈希地址 h0 = H(key) 產生衝突時,以 h0 爲基礎,產生另外一個地址 h1,若 h1 仍然衝突,再以 h0 爲基礎,產生哈希地址 h2,直到不衝突爲止!

初始哈希地址:H0 = H(key)
衝突哈希地址:Hi = (H0 + Di) % m i = 1,2,...,n

① 線性探測再散列

Di = 1,2,3,...,m-1

② 二次探測再散列

Di = 1^2, -1^2, 2^2, -2^2,.... k^2, -k^2 (k <= m/2)

③ 僞隨機探測再散列

Di = 僞隨機數序列

查找結束條件:直到找到一個空單元或者查遍全表

> 再哈希法

同時構造多個不一樣的哈希函數,當哈希發生衝突時,使用下一個哈希函數,直到再也不產生衝突。

這種方法不易產生聚焦,但增長了計算時間!

> 鏈地址法

產生的哈希衝突加入鏈表

三、Java 中哈希值的計算規則

① 建立 int result,賦值非0

② 對於在 equals() 方法中測試的每一個字段 f,經過如下方式計算哈希值 c

  • boolean: (f ? 0 : 1)
  • byte, char, shortint: (int)f
  • long: (int)(f ^ (f >>> 32))
  • float: Float.floatToIntBits(f)
  • double: Double.doubleToLongBits(f) 並像 long 型同樣處理返回結果
  • object: 使用 hashCode() 方法,若爲 null 返回 0
  • array: 將每一個字段視爲單獨的元素並以遞歸方式計算哈希值,並按照下面所述方式組合最終結果

③ 組合哈希值 cresult

result = 37 * result + c

④ 返回 result

相關文章
相關標籤/搜索