假設你們班級100個同學每個人的學號是由院系-年級-班級和編號組成,例如學號為01100168表示是1系,10級1班的68號。為了快速查詢到68號的成績資訊,可以建立一張表,但是不能用學號作為下標,學號的數值實在太大。因此將學號除以1100100取餘,即得到編號作為該錶的下標,那麼,要查詢學號為01100168的成績的時候,只要直接訪問表下標為68的資料即可。這就能夠在o(1)時間複雜度內完成成績查詢。
實際上這裡就用到了雜湊的思想。本文重在介紹雜湊的思想以及雜湊需要考慮的問題。
理想雜湊表(雜湊表)是乙個包含關鍵字的具有固定大小的陣列,它能夠以常數時間執行插入,刪除和查詢操作。
通過前面的描述,我們已經了解了一些基本概念,現在來看乙個例項。
假設有乙個大小為7的表,現在,要將13,18,19,50,20雜湊到表中。
計算13 % 7得到6,因此將13放到下標為6的位置:01
2345
613計算18 % 7得到4,因此將18放到下標為4的位置:01
2345
61813計算19 % 7得到5,因此將19放到下標為5的位置:01
2345
6181913
計算50 % 7得到1,因此將50放到下標為1的位置:01
2345
6501819
13計算20 % 7得到6,因此將20放到下標為6的位置,但是此時6的位置已經被占用了,因此就產生了雜湊衝突,關於雜湊衝突的解決,我們後面再介紹。
將資料雜湊之後,如何從表中查詢呢?例如,查詢數值為50的資料位置,只需要計算50 % 7,得到下標1,訪問下標1的位置即可。但是如果考慮雜湊衝突,就沒有那麼簡單了。
通過這個例項,了解了以下幾個概念:
解決雜湊衝突通常有以下幾種方法:01
2345
6501819
13如果再要插入元素20,則在下標為6的位置儲存表頭,而表的內容是13和20。
這種方法的特點是需要另外分配新的單元來儲存雜湊到同乙個位置的資料。
查詢的時候,除了根據計算出來的雜湊值找到對應位置外,還需要在鍊錶上進行搜尋。而在單鏈表上的查詢速度是很慢的。另外雜湊函式如果設計得好,衝突的概率其實也會很小。
而開放定址法的思想是,如果衝突發生,就選擇另外乙個可用的位置。
而開放定址法中也有常見的幾種策略。
還是以前面的為例:01
2345
6501819130
1234
562050
1819
13但這種方式的乙個問題是,可能造成一次聚集,因為一旦衝突發生,為了處理衝突就會占用下乙個位置,而如果衝突較多時,就會出現資料都聚集在一塊區域。這樣就會導致任何關鍵字都需要多次嘗試才可能解決衝突。
顧名思義,如果說前面的探測函式是f(i)= i % 7,那麼平方探測法就是f(i)= (i^2 )% 7。
但是這也同樣會產生二次聚集問題。
為了避免聚集,在探測時選擇跳躍式的探測,即再使用乙個雜湊函式,用來計算探測的位置。假設前面的雜湊函式為hash1(x),用於探測的雜湊函式為hash2(x),那麼一種流行的選擇是f(i) = i * hash2(x),即第一次衝突時探測hash1(x)+hash2(x)的位置,第二次探測
hash1(x)+2hash2(x)的位置。
可以看到,無論是哪種開放定址法,它都要求表足夠大。
我們前面也說到,雜湊表可以認為是具有固定大小的陣列,那麼如果插入新的資料時雜湊表已滿,或者雜湊表所剩容量不多該怎麼辦?這個時候就需要再雜湊,常見做法是,建立乙個是原來兩倍大小的雜湊表,將原來表中的關鍵字重新雜湊到新錶中。
雜湊表應用很廣泛。例如做檔案校驗或數字簽名。當然還有快速查詢功能的實現。例如,redis中的字典結構就使用了雜湊表,使用murmurhash演算法來計算字串的hash值,並採用拉鍊法處理衝突,,當雜湊表的裝載因子(關鍵字個數與雜湊表大小的比)接近某個大小時,進行再雜湊。
乙個設計良好的雜湊表能夠幾乎在o(1)時間複雜度內完成插入,刪除和查詢,但前提是雜湊函式設計得足夠優雅,以及有著合適雜湊衝突解決方案。常見衝突解決方案有:
其中拉鍊法在實際中是很常見的一種解決方案。
拼寫單詞 仿造雜湊表的思想
給你乙份 詞彙表 字串陣列 words 和一張 字母表 字串 chars。假如你可以用 chars 中的 字母 字元 拼寫出 words 中的某個 單詞 字串 那麼我們就認為你掌握了這個單詞。注意 每次拼寫時,chars 中的每個字母都只能用一次。返回詞彙表 words 中你掌握的所有單詞的 長度之...
雜湊表(雜湊表)的定義
chapter 雜湊表 雜湊表 1.雜湊表 雜湊表 的定義 2.雜湊表是怎麼進行查詢的?3.雜湊函式設計 直接定址法 4.雜湊函式設計 除留餘數法 5.雜湊衝突處理 開放定址法 6.雜湊衝突處理 鏈位址法 7.雜湊表的鏈位址法實現 8.linux核心中的hash與bucket 9.引入雜湊桶的概念來...
雜湊表(雜湊表)的實現
雜湊函式直接用key size的形式,size為雜湊表的大小。衝突處理採用平方探測法,為保證可以探測到整個雜湊表空間,雜湊表大小設定為4k 3形式的素數。當雜湊表中的元素過多時會造成效能下降,這時應該倍增雜湊表的大小,重新計算原來雜湊表中每個元素在新的雜湊表中的位置。雜湊表的實現 hashtable...