散列函數:把查找表中的關鍵字映射成該關鍵字對應的地址。
Hash(key)=Addr
這里的地址可以是數組下標,索引或內存地址等。
沖突:不同的關鍵字映射到同一地址(這些關鍵字稱為同義詞)
散列表:根據關鍵字而進行直接訪問的數據結構。
散列函數的構造方法
采用何種構造散列函數的方法取決于關鍵字集合的情況,目標是為了盡量降低產生沖突的可能性。
1.直接定址法
H(key)=axkey+b
計算簡單,不會產生沖突。
適合關鍵字的分布基本連續的情況,若關鍵字分布不連續,空位較多,則會造成存儲空間的浪費。
2.除留余數法
假設散列表長m,取一個不大于m但最接近或等于m的質數p
H(key)=key%p
選好p,使得每個關鍵字通過該函數轉換后等概率地映射到散列空間上的任一地址,從而減少沖突的可能性。
3.數字分析法
設關鍵字是r進制數,而r個數碼(0,1,...,r-1)在各位上出現的頻率不一定相同,可能在某些位上分布均勻一些,每種數碼出現的機會均等;而在某些位上分布不均勻,只有某幾種數碼經常出現。此時應選取數碼分布較為均勻的若干位作為散列地址。
這種方法適合于已知的關鍵字集合,若更換了關鍵字,則需重新構造新的散列函數。
4.平方取中法
取關鍵字的平方值的中間幾位作為散列地址。
這種方法得到的散列地址與關鍵字的每位都有關系,因此使得散列地址分布比較均勻。
適用于關鍵字的每位取值都不夠均勻或均小于散列地址所需要的位數。
5.折疊法
將關鍵字分割成位數相同的幾部分(最后一部分的位數可以短一些),然后取這幾部分的疊加作為散列地址。
適用于關鍵字位數很多,且關鍵字中每位上的數字分布大致均勻時
處理沖突的方法
散列函數H(key),Hi表示發生沖突后第i次探測的散列地址
1.開放定址法
可存放新表項的空閑地址即向它的同義詞表項開放,又向它的非同義詞表項開放
Hi=(H(key)+di)%m
i=0,1,2...,k(k<=m-1)
m為散列表表長
di為增量序列
線性探測法
di=0,1,2,...,m-1
沖突發生時,順序查看表中下一個單元
會造成大量元素在相鄰的散列地址上堆積起來,降低了查找效率
平方探測法(二次探測法)
di=02,12,-12,22,-22,...,k2,-k^2(k<=m/2)
m必須是一個可以表示成4k+3的素數
可以避免出現堆積問題,缺點是不能探測到散列表上所有單元,但至少能探測到一半單元
再散列法(雙散列法)
di=Hash2(key)
Hi=(H(key)+ixHash2(key))%m
偽隨機序列法
di=偽隨機數序列
邏輯刪除?
2.鏈接法
把所有的同義詞存儲在一個線性鏈表中
適用于經常進行插入和刪除的情況
散列查找及性能分析
裝填因子
α=表中記錄數n/散列表長度m
散列表的平均長度依賴于散列表的裝填因子α,而不直接依賴于n或m