雜湊表的概念
雜湊表(hash table)也叫雜湊表,是根據關鍵碼值(key value)而直接進行訪問的資料結構。它通過把關鍵碼值對映到雜湊表中的乙個位置來訪問記錄,以加快查詢的速度。這個對映函式就做雜湊函式,存放記錄的陣列叫做雜湊表。
雜湊儲存的基本思路
以資料中每個元素的關鍵字k為自變數,通過雜湊函式h(k)計算出函式值,以該函式值作為一塊連續儲存空間的的單元位址,將該元素儲存到函式值對應的單元中。
雜湊表查詢的時間複雜度
雜湊表儲存的是鍵值對,其查詢的時間複雜度與元素數量多少無關,雜湊表在查詢元素時是通過計算雜湊碼值來定位元素的位置從而直接訪問元素的,因此,雜湊表查詢的時間複雜度為o(1)。
雜湊函式的構造方法
雜湊表處理衝突主要有開房定址法、再雜湊法、鏈位址法(拉鍊法)和建立乙個公共溢位區四種方法。
1. 直接定址法
取關鍵字或者關鍵字的某個線性函式值作為雜湊位址,即h(key)=key或者h(key)=a*key+b(a,b為整數),這種雜湊函式也叫做自身函式.如果h(key)的雜湊位址上已經有值了,那麼就往下乙個位置找,知道找到h(key)的位置沒有值了就把元素放進去.
2. 數字分析法
分析一組資料,比如一組員工的出生年月,這時我們發現出生年月的前幾位數字一般都相同,因此,出現衝突的概率就會很大,但是我們發現年月日的後幾位表示月份和具體日期的數字差別很大,如果利用後面的幾位數字來構造雜湊位址,則衝突的機率則會明顯降低.因此數字分析法就是找出數字的規律,盡可能利用這些資料來構造衝突機率較低的雜湊位址.
3. 平方取中法
取關鍵字平方後的中間幾位作為雜湊位址.
4. 摺疊法
摺疊法即將關鍵字分割成位數相同的幾部分,最後一部分位數可以不同,然後取這幾部分的疊加和(注意
:疊加和時去除進製)作為雜湊位址.數字疊加可以有移位疊加和間界疊加兩種方法.移位疊加是將分割後的每一部分的最低位對齊,然後相加;間界疊加是從一端向另一端沿分割界來回摺疊
,然後對齊相加.
5. 隨機數法
選擇乙個隨機數,去關鍵字的隨機值作為雜湊位址,通常用於關鍵字長度不同的場合.
6. 除留餘數法
取關鍵字被某個不大於雜湊表表長m的數p除后所得的餘數為雜湊位址.即h(key)=key mod p,p<=m.不僅可以對關鍵字直接取模,也可在摺疊、平方取中等運算之後取模。對p的選擇很重要,一般取素數或m,若p選得不好,則很容易產生衝突。
雜湊表如何處理衝突
雜湊表處理衝突主要有開放定址法、再雜湊法、鏈位址法(拉鍊法)和建立乙個公共溢位區四種方法。
通過構造效能良好的雜湊函式,可以減少衝突,但一般不可能完全避免衝突,因此解決衝突是雜湊法的另乙個關鍵問題。建立雜湊表和查詢雜湊表都會遇到衝突,兩種情況下解決衝突的方法應該一致。下面以建立雜湊表為例,說明解決衝突的方法。常用的解決衝突方法有以下四種:
1.開放定址法
這種方法也稱再雜湊法,其基本思想是:當關鍵字key的雜湊位址p=h(key)出現衝突時,以p為基礎,產生另乙個雜湊位址p1,如果p1仍然衝突,再以p為基礎,產生另乙個雜湊位址p2,…,直到找出乙個不衝突的雜湊位址pi ,將相應元素存入其中。這種方法有乙個通用的再雜湊函式形式:hi=(h(key)+di)%m i=1,2,…,n,其中h(key)為雜湊函式,m 為表長,di稱為增量序列。增量序列的取值方式不同,相應的再雜湊方式也不同。主要有以下三種:
(1)線性探測再雜湊
di=1,2,3,…,m-1
(2)二次探測再雜湊
di=12,-12,22,-22,…,k2,-k2 ( k<=m/2)
這種方法的特點是:衝突發生時,在表的左右進行跳躍式探測,比較靈活。
(3)偽隨機探測再雜湊
di=偽隨機數序列。
具體實現時,應建立乙個偽隨機數發生器,(如i=(i+p) % m),並給定乙個隨機數做起點。
例如,已知雜湊表長度m=11,雜湊函式為:h(key)= key % 11,則h(47)=3,h(26)=4,h(60)=5,假設下乙個關鍵字為69,則h(69)=3,與47衝突。如果用線性探測再雜湊處理衝突,下乙個雜湊位址為h1=(3 + 1)% 11 = 4,仍然衝突,再找下乙個雜湊位址為h2=(3 + 2)% 11 = 5,還是衝突,繼續找下乙個雜湊位址為h3=(3 + 3)% 11 = 6,此時不再衝突,將69填入5號單元。如果用二次探測再雜湊處理衝突,下乙個雜湊位址為h1=(3 + 12)% 11 = 4,仍然衝突,再找下乙個雜湊位址為h2=(3 - 12)% 11 = 2,此時不再衝突,將69填入2號單元。如果用偽隨機探測再雜湊處理衝突,且偽隨機數序列為:2,5,9,……..,則下乙個雜湊位址為h1=(3 + 2)% 11 = 5,仍然衝突,再找下乙個雜湊位址為h2=(3 + 5)% 11 = 8,此時不再衝突,將69填入8號單元。
從上述例子可以看出,線性探測再雜湊容易產生「二次聚集」,即在處理同義詞的衝突時又導致非同義詞的衝突。例如,當表中i, i+1 ,i+2三個單元已滿時,下乙個雜湊位址為i, 或i+1 ,或i+2,或i+3的元素,都將填入i+3這同乙個單元,而這四個元素並非同義詞。線性探測再雜湊的優點是:只要雜湊表不滿,就一定能找到乙個不衝突的雜湊位址,而二次探測再雜湊和偽隨機探測再雜湊則不一定。
2.再雜湊法
這種方法是同時構造多個不同的雜湊函式:
hi=rh1(key),i=1,2,3,…,n.
當雜湊位址hi=rh1(key)發生衝突時,再計算hi=rh2(key)……,直到衝突不再產生。這種方法不易產生聚集,但增加了計算時間。
3.鏈位址法
這種方法的基本思想是將所有雜湊位址為i的元素構成乙個稱為同義詞鏈的單鏈表,並將單鏈表的頭指標存在雜湊表的第i個單元中,因而查詢、插入和刪除主要在同義詞鏈中進行。若選定的雜湊表長度為m,則可將雜湊表定義為乙個由m個頭指標組成的指標陣列t[0..m-1]。凡是雜湊位址為i的結點,均插入到以t[i]為頭指標的單鏈表中。t中各分量的初值均應為空指標。鏈位址法適用於經常進行插入和刪除的情況。
例如,已知一組關鍵字(32,40,36,53,16,46,71,27,42,24,49,64),雜湊表長度為13,雜湊函式為:h(key)= key % 13,則用鏈位址法處理衝突的結果如圖8.27所示:
圖8.27鏈位址法處理衝突時的雜湊表
本例的平均查詢長度 asl=(1*7+2*4+3*1)/12=1.5
拉鍊法的優點
與開放定址法相比,拉鍊法有如下幾個優點:
(1)拉鍊法處理衝突簡單,且無堆積現象,即非同義詞決不會發生衝突,因此平均查詢長度較短;
(2)由於拉鍊法中各煉表上的結點空間是動態申請的,故它更適合於造表前無法確定表長的情況;
(3)開放定址法為減少衝突,要求裝填因子α較小,故當結點規模較大時會浪費很多空間。而拉鍊法中可取α≥1,且結點較大時,拉鍊法中增加的指標域可忽略不計,因此節省空間;
(4)在用拉鍊法構造的雜湊表中,刪除結點的操作易於實現。只要簡單地刪去鍊錶上相應的結點即可。而對開放位址法構造的雜湊表,刪除結點不能簡單地將被刪結點的空間置為空,否則將截斷在它之後填入雜湊表的同義詞結點的查詢路徑。這是因為各種開放位址法中,空位址單元(即開放位址)都是查詢失敗的條件。 因此在用開放位址法處理衝突的雜湊表上執行刪除操作,只能在被刪結點上做刪除標記,而不能真正刪除結點。
拉鍊法的缺點
拉鍊法的缺點是:指標需要額外的空間,故當結點規模較小時,開放定址法較為節省空間,而若將節省的指標空間用來擴大雜湊表的規模,可使裝填因子變小,這又減少了開放定址法中的衝突,從而提高平均查詢速度。
4、建立公共溢位區
這種方法的基本思想是:將雜湊表分為基本表和溢位錶兩部分,凡是和基本表發生衝突的元素,一律填入溢位表.(注意:在這個方法裡面是把元素分開兩個表來儲存)
衝突太多了怎麼辦?
當衝突太多的時候,我們一般採用的方法時拉鍊法,採用拉鍊法的原因是動態申請空間,至於優點在上面已經闡述了.衝突太多的時候會產生堆積狀態,我們將h(key)相同的關鍵字都統一放到乙個鏈裡,當出現衝突的時候我們就把該元素接在鍊錶後面,這樣可以避免產生堆積現象,縮短平均查詢長度.
當資料表太小,而資料太多的時候怎麼辦?
當資料表太小資料太多可以通過建立乙個溢位表,專門用來存放雜湊表中放不下的記錄.
ps:對於最後兩個問題我本人還不是理解得十分透徹,希望看到這篇文章並且對最後兩個問題有想法的童鞋積極發表一下自己的見解,感激不盡.
雜湊表總結
雜湊表的概念 雜湊表 hash table 也叫雜湊表,是根據關鍵碼值 key value 而直接進行訪問的資料結構。它通過把關鍵碼值對映到雜湊表中的乙個位置來訪問記錄,以加快查詢的速度。這個對映函式就做雜湊函式,存放記錄的陣列叫做雜湊表。雜湊儲存的基本思路 以資料中每個元素的關鍵字k為自變數,通過...
雜湊表 (自我總結
雜湊表,就是一種結構資料,它以犧牲空間為代價節約時間,其實,我在做題的過程中,並沒有什麼明顯的感覺,做得有些一頭霧水。雜湊表的運用感覺還是挺簡單的,不過運動道題目,以什麼值為下標,儲存其值,如何去查詢思考,如果單方面的看雜湊表是簡單的,就是在於如何放在題目中運用。int hash 計算雜湊表tabl...
雜湊表應用總結
處理雜湊表衝突的方法主要有除留餘數法,平方探測方法,以下兩題具體介紹兩種方法的使用方法 time limit 400 ms memory limit 65536 kib submit statistic problem description 給定的一組無重複資料的正整數,根據給定的雜湊函式建立其對...