目錄
哈希表
-
哈希表定義
- 哈希表(Hash Table)又稱散列表,是除順序表存儲結構、鏈接表存儲結構和索引表存儲結構之外的又一種存儲線性表的存儲結構。
-
哈希表(散列表)的基本概念
-
基本思想:
- 記錄的存儲位置與關鍵字之間存在對應關係
-
優點:
- 查找效率高
-
缺點:
- 空間效率低
-
散列方法:
- 選取某個函數,依該函數按關鍵字計算元素的存儲位置,並按此存放;
- 查找時,由同一個函數對給定 k 計算地址,將 k 地址單元中有關元素關鍵碼進行對比,確定查找是否成功。
-
散列函數:
- 散列方法中使用的轉換函數
-
散列表:
- (按上述思想構成的表)根據關鍵碼值(Key)直接進行訪問的數據結構。
- 也就是說,它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。
- 這個映射函數叫做散列函數,存放記錄的數組叫做散列表。
-
衝突:
- 不同的關鍵碼映射到同一個散列地址
-
同義詞:
- 具有相同函數值的多個關鍵字
-
-
哈希表基本思路:
- 設要存儲的對象個數爲n,設置一個長度爲m(m≥n)的連續內存單元。
- 以線性表中每個對象的關鍵字ki(0≤i≤n-1)爲自變量,通過一個稱爲哈希函數的函數h(ki),把ki映射爲內存單元的地址(或稱下標)h(ki),並把該對象存儲在這個內存單元中。
- h(ki)也稱爲哈希地址(又稱散列地址)。
- 把如此構造的線性表存儲結構稱爲哈希表。
-
哈希衝突:
- 對於兩個關鍵字ki和kj(i≠j),有ki≠kj(i≠j),但會出現h(ki)=h(kj)。
- 通常把這種具有不同關鍵字而具有相同哈希地址的對象稱做“同義詞”,由同義詞引起的衝突稱作同義詞衝突。
- 在哈希表存儲結構的存儲中,同義詞衝突是很難避免的,除非關鍵字的變化區間小於等於哈希地址的變化區間,而這種情況當關鍵字取值不連續時是非常浪費存儲空間的。
- 就是當使用哈希函數計算哈希地址時,函數計算產生的哈希值是有限的,而數據可能比較多,導致產生了誤差從而不同的關鍵字計算得出了相同的哈希地址
- 通常的實際情況是關鍵字的取值區間遠大於哈希地址的變化區間。
-
哈希表設計
- 哈希表設計主要需要解決哈希衝突。實際中哈希衝突是難以避免的
-
哈希表結構
-
哈希表創建
-
哈希表插入
-
哈希表查找
-
哈希衝突產生因素
-
1.與裝填因子α有關
- 裝填因子α是指哈希表中已存入的元素數n與哈希地址空間大小m的比值,即α=n/m
- 裝填因子α=存儲的記錄個數n/哈希表的大小m=n/m
- α越小,衝突的可能性就越小,α越小說明存儲存儲的記錄數越少或哈希表大小越大,關鍵字的變化區間就會小於等於哈希地址的變化區間;
- α越大(最大可取1),衝突的可能性就越大,α越大說明存儲存儲的記錄數越多或哈希表大小越小,關鍵字的取值區間遠大於哈希地址的變化區間。
- 這很容易理解,因爲α越小,哈希表中空閒單元的比例就越大,所以待插入元素同已插入的元素髮生衝突的可能性就越小;
- 反之, α越大,哈希表中空閒單元的比例就越小,所以待插入元素同已插入的元素衝突的可能性就越大;
- 另一方面, α越小,存儲空間的利用率就越低;反之,存儲空間的利用率也就越高。
- 爲了既兼顧減少衝突的發生,又兼顧提高存儲空間的利用率這兩個方面,通常使最終的控制在0.6~0.9的範圍內。
- 裝填因子α是指哈希表中已存入的元素數n與哈希地址空間大小m的比值,即α=n/m
-
2.與所採用的哈希函數有關
- 若哈希函數選擇得當,就可使哈希地址儘可能均勻地分佈在哈希地址空間上,從而減少衝突的發生;
- 否則,若哈希函數選擇不當,就可能使哈希地址集中於某些區域,從而加大沖突的發生。
-
3.與解決衝突的哈希衝突函數(方法)有關。
- 解決衝突的哈希衝突函數(方法)選擇的好壞也將減少或增加發生衝突的可能性。
-
-
哈希函數的構造方法
-
目的
- 構造哈希函數的目標是使得到的哈希地址儘可能均勻地分佈在n個連續內存單元地址上,同時使計算過程儘可能簡單以達到儘可能高的時間效率。
- 根據關鍵字結構和分佈可以構造出很多種不同的哈希函數
-
1. 直接定址法
- 直接定址法是以關鍵字k本身或關鍵字加上某個數值常量c作爲哈希地址的方法。
- 直接定址法的哈希函數h(k)爲:
- h(k)=k+c
- 如:h(學號) = 學號-201001001
- 這種哈希函數計算簡單,並且不可能有衝突發生。
- 使用條件
- 當關鍵字的分佈基本連續時,可用直接定址法的哈希函數;
- 否則,若關鍵字分佈不連續將造成內存單元的大量浪費。
-
2. 除留餘數法
- 除留餘數法是用關鍵字k除以某個不大於哈希表長度m的數p所得的餘數作爲哈希地址的方法。
- 除留餘數法使得每個關鍵字通過該函數轉換後映射到哈希表範圍內的任意地址上的概率相等(把n個記錄按關鍵字值映射到0~m-1的哈希空間中),從而儘可能減少發生衝突的可能性
- 除留餘數法的哈希函數h(k)爲:
- h(k)=k mod p (mod爲求餘運算,即k%p,p≤m)
- p最好是不大於哈希表長度m的質數(素數)。
- 除留餘數法是用關鍵字k除以某個不大於哈希表長度m的數p所得的餘數作爲哈希地址的方法。
-
3. 數字分析法
- 該方法是提取關鍵字中取值較均勻的數字位作爲哈希地址的方法。
- 條件
- 它適合於所有關鍵字值都已知的情況,並需要對關鍵字中每一位的取值分佈情況進行分析。
- 例如
- 對於一組關鍵字:{92317602,92326875,92739628,92343634,92706816,92774638,92381262,92394220}
- 通過分析可知,每個關鍵字從左到右的第1、2、3位和第6位取值較集中,不宜作爲哈希函數,剩餘的第4、5、7和8位取值較分散,可根據實際需要取其中的若干位作爲哈希地址。
- 若取最後兩位作爲哈希地址,則哈希地址的集合爲{2,75,28,34,16,38,62,20}。
- 該方法是提取關鍵字中取值較均勻的數字位作爲哈希地址的方法。
-
4.平方取中法
- 假設關鍵字是1234,那它的平方就是1522756,再抽取中間的3位就是277
- 條件
- 適合不知道關鍵字的分佈,而位數又不是很大的情況。
-
5.摺疊法
- 將關鍵字從左到右分割成位數相等的幾個部分,然後將這幾部分疊加求和,並按散列表表長,取後幾位作爲散列地址。
- 比如關鍵字是9876543210,散列表表長爲三位,我們將它分成四組,987|654|321|0,然後將他們疊加求和等於1962,再求後三位得到散列地址962。
- 條件
- 適合事先不知道關鍵字的分佈,關鍵字位數叫多的情況。
-
-
哈希衝突解決方法
-
1. 開放定址法
- 開放定址法是一類以發生衝突的哈希地址爲自變量,通過某種哈希衝突函數得到一個新的空閒的哈希地址的方法。
- 開放定址法中哈希表空閒單元既向同義詞關鍵字開放又向發生衝突的非同義詞開放
- 哈希表中的一個地址存放的是同義詞還是非同義詞要看是誰先佔用他,和構造哈希表元素排列順序有關
- 根據衝突地址找到新的空閒哈希地址的方法有線性探測法、平方探測法、未隨機序列法、雙哈希函數法等
-
(1)線性探測法
- 線性探測法是從發生衝突的地址(設爲d)開始,依次探測d的下一個地址(當到達下標爲m-1的哈希表表尾時,下一個探測的地址是表首地址0,任何依次探測0-d的位置),直到找到一個空閒單元爲止(當m≥n時一定能找到一個空閒單元)。
- 線性探測法的數學遞推描述公式爲:
- d0=h(k)
- di=(di-1+1) mod m (1≤i≤m-1)
- 模m是爲了保證找到的位置在0~m-1的有效空間中。
- 堆積問題
- 當連續出現若干個同義詞時(設第一個同義詞佔用單元d0),這連續的若干個同義詞,將佔用哈希表的d0、d0+1、d0+2等單元,隨後任何本該在d0、d0+1、d0+2等單元上的哈希映射都會由於前面的同義詞堆積而產生衝突,儘管隨後的這些關鍵字並沒有同義詞
- 非同義詞衝突:
- 採用線性探測法的缺點是可能產生非同義詞衝突
- 哈希函數值不相同的兩個記錄爭奪同一個後繼哈希地址,這是由於堆積(或聚集)現象引起的。
-
(2)平方探測法
- 設發生衝突的地址爲d0,則平方探測法的探測序列爲:d0+1²,d0-1²,d0+2²,d0-2²…。
- 平方探測法的數學描述公式爲:
- d0=h(k)
- di=(d0± i²) mod m (1≤i≤m-1)
- 平方探測法是一種較好的處理衝突的方法,可以避免出現堆積問題。
- 因爲是在當前衝突地址的基礎上進行平方相加,避免了發生衝突在同一位置區間查找空餘位置
- 它的缺點是不能探測到哈希表上的所有單元,但至少能探測到一半單元。
-
(3)僞隨機探測
- 按順序決定哈希值時,如果發生衝突,通過隨機函數生成一個數,在原來哈希值的基礎上加上隨機數,直到該哈希值不發生衝突
-
2. 拉鍊法
- 拉鍊法是把所有的同義詞用單鏈錶鏈接起來的方法。
- 拉鍊法中,哈希表每個單元中存放的不再是記錄本身,而是相應同義詞單鏈表的頭指針。
- 由於單鏈表中可插入任意多個節點,所以拉鍊法的裝填因子α根據同義詞的多少既可以設定爲大於1,也可以設定爲小於或等於1,通常取α=1。
- 優點
- 拉鍊法處理衝突簡單且無堆積現象,即非同義詞絕不會發生衝突,因此平均查找長度較短
- 由於拉鍊法中個單鏈表上的節點空間是動態申請的,故他更合適於造表前無法確定表長的情況
- 開放定值法爲減少衝突要求裝填因子α較小,故當數據規模較大時會浪費很多空間,而拉鍊法中可取α>=1,且元素較大時拉鍊法中增加的指針與可忽略不計,因此節省空間
- 在用拉鍊法構造的哈希表中進行刪除節點的操作,更加容易實現
- 缺點
- 指針需要額外的空間,故當元素規模較小時開放定值法較爲節省空間,若將節省的指針空間用來擴大,哈希表的規模可使裝填因子α變小,這又減少了開放定值法中的衝突,從而提高了平均查找速度
-