雜湊表概述

2021-08-20 04:44:40 字數 4172 閱讀 9860

雜湊表(hash table,也叫雜湊表),是根據關鍵碼值(key value)而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做雜湊表或雜湊表。具體表現為:

儲存位置 =f(key);
1.在儲存時,通過雜湊函式計算記錄的雜湊位址,並按此雜湊位址儲存該記錄。

2.當查詢記錄時,我們通過同樣的雜湊函式計算記錄的雜湊位址,按此雜湊位址訪問該記錄。簡單說,怎麼存進去的,就怎麼取出來。由於訪問用的同乙個雜湊函式,因此結果當然也是相同的。

因此,雜湊技術,既是一種儲存方法,也是一種查詢方法。雜湊結束最適合的求解問題是查詢與給定值相等的記錄,但不適合能對應很多記錄的情況。比如,乙個班級的所有男同學,給定關鍵字為「男」去查詢。另外,它也不適合範圍查詢。比如,查詢乙個班級18~22歲的同學,則在雜湊表中沒法進行。還有獲得記錄中的最大值和最小值等結果也無法從雜湊表中計算出來等等。

乙個好的hash函式應同時具備以下兩個條件:

1.計算簡單

可能設計乙個演算法可以保證所有的關鍵字都不會產生衝突,但是這個演算法需要很複雜的計算,會耗費很多時間,這對於需要頻繁地查詢來說,就會大大降低查詢的效率。因此,雜湊函式的計算時間不應該超過其他查詢技術與關鍵字比較的時間

2.雜湊位址分布均勻

雜湊位址均勻地分布在儲存空間中,這樣可以保證儲存空間的有效利用,並減少了為處理衝突而耗費的時間。

1.直接定址法

儲存位置 = f(key) = a*key+b(a,b為常數);
這樣的雜湊函式的優點就是簡單、均勻,也不會產生衝突,但問題是這需要事先知道關鍵字的分布情況,適合查詢表較小且連續的情況

2.數字分析法

分析關鍵字的特點,選取關鍵字的一部分來計算雜湊儲存位置的方法。數字分析法,通常適合處理關鍵字位數比較大的情況,如果事先知道關鍵字的分布且關鍵字的若干位分布較均勻。

3.平方取中法

假設關鍵字是1234,那麼它的平方就是1522756,再抽取中的3位就是227,用作雜湊位址。平方取中法比較適合於不知道關鍵字的分布,而位數又不是很大的情況。

4.除留餘數法

儲存位置 = f(key) = key

mod p(p≤m,m為雜湊表長);

mod取模的意思。事實上,這方法不僅可以對關鍵字直接取模,也可以在摺疊、平方取中後再取模。很顯然,本方法的關鍵在於選擇合適的p,p如果選得不好,就可能會容易產生衝突。因此,根據前輩們的經驗,若雜湊表表長為m,通常p為小於或等於表長(最好接近m)的最小質數或不包含小於20質因子的合數。

5.隨機數法

儲存位置 = f(key) = random(key)(random是隨機函式,key為隨機函式的種子);
選擇乙個隨機函式,取關鍵字的隨機函式值為它的雜湊位址。當關鍵字的長度不等時,採用這個方法構造雜湊函式是比較合適的。

以上五種雜湊函式構造方法,不論採用哪一種,都有可能存在衝突,因此處理hash衝突也是需要被考慮的。

1.開放定址法

fi(key) = (f(key)+di) mod m (di=1,2,3,......,m-1);
用開放定址法解決衝突的做法是:當衝突發生時,使用某種探測技術在雜湊表中形成乙個探測序列。沿此序列逐個單元地查詢,直到找到給定的關鍵字,或者碰到乙個開放的位址(即該位址單元為空)為止(若要插入,在探查到開放的位址,則可將待插入的新結點存人該位址單元)。查詢時探測到開放的位址則表明表中無待查的關鍵字,即查詢失敗。

比如說,我們的關鍵字集合為,表長為12。 我們用雜湊函式f(key) = key mod l2。

當計算前s個數時,都是沒有衝突的雜湊位址,直接存入:

計算key = 37時,發現f(37) = 1,此時就與25所在的位置衝突。於是我們應用上面的公式f(37) = (f(37)+1) mod 12 = 2。於是將37存入下標為2的位置。這其實就是房子被人買了於是買下一間的作法:。

接下來22,29,15,47都沒有衝突,正常的存入:

到了 key=48,我們計算得到f(48) = 0,與12所在的0位置衝突了,不要緊,我們f(48) = (f(48)+1) mod 12 = 1,此時又與25所在的位置衝突。於是f(48) = (f(48)+2) mod 12=2,還是衝突……一直到 f(48) = (f(48)+6) mod 12 = 6時,才有空位,機不可失,趕快存入:

我們把這種解決衝突的開放定址法稱為線性探測法

從這個例子我們也看到,我們在解決衝突的時候,還會碰到如48和37這種本來都不是同義詞卻需要爭奪乙個位址的情況,我們稱這種現象為堆積。很顯然,堆積的出現,使得我們需要不斷處理衝突,無論是存入還是查詢效率都會大大降低。

考慮深一步,如果發生這樣的情況,當最後乙個key=34,f(key)=10,與22所在的位置衝突,可是22後面沒有空位置了,反而它的前面有乙個空位置,儘管可以 不斷地求餘數後得到結果,但效率很差。因此我們可以改進di = 12, -12, 22, -22,……, q2, -q2 (q <= m/2),這樣就等於是可以雙向尋找到可能的空位置。對於34來說,我 們取di即可找到空位置了。另外增加平方運算的目的是為了不讓關鍵字都聚集在 某一塊區域。我們稱這種方法為二次探測法

fi(key) = (f(key)+di) mod m (di = 1^2

, -1

^2, 2^2

, -2

^2,……, q

^2, -q

^2, q <=m/2

);

還有一種方法是,在衝突時,對於位移量 di 採用隨機函式計算得到,我們稱之為隨機探測法

此時一定會有人問,既然是隨機,那麼查詢的時候不也隨機生成辦嗎?如何可以獲得相同的位址呢?這是個問題。這裡的隨機其實是偽隨機數。偽隨機數是說,如果我們設定隨機種子相同,則不斷呼叫隨機函式可以生成不會重複的數列,我們在查詢時,用同樣的隨機種子,它每次得到的數列是相同的,相同的 di 當然可以得到相同的雜湊位址。

fi(key) = (f(key)+di) mod m (di是乙個隨機數列);
總之,開放定址法只要在雜湊表未填滿時,總是能找到不發生衝突的位址,是我們常用的解決衝突的辦法。

2.再雜湊函式法

對於我們雜湊表來說,我們事先準備多個雜湊函式。

fi(key) = rhi(key) (i=1,2,3...,k);
這裡rhi就是不同的雜湊函式,把之前的5個雜湊函式都可以用上。這種方法能夠使得關鍵字不產生聚集,但相應地增加了計算的時間。

3.鏈位址法

將所有關鍵字為同義詞的記錄儲存在乙個單鏈表中,我們稱這種表尾同義詞子表,在雜湊表中只儲存所有同義詞子表的頭指標。此時,已經不存在什麼衝突位址的問題,無論有多少個衝突,都只是在當前位置給單鏈表增加結點的問題。鏈位址法對於可能會造成很多衝突的雜湊函式來說,提供了絕不會出現找不到位址的保障。當然,也就帶來了查詢時需要遍歷單鏈表的效能損耗。

4.公共溢位區法

將衝突的部分,單獨存放在乙個公共的溢位區裡面。在查詢時,對給定值通過雜湊函式計算出雜湊位址後,先於基本表的相應位置進行比對,如果相等,則查詢成功;如果不相等,則到溢位表去進行順序查詢。如果相對於基本表而言,有衝突的資料很少的情況下,公共溢位區的結構對查詢效能來說還是非常高的。

如果沒有衝突,雜湊表查詢是所有查詢演算法中效率最高的,因為它的時間複雜度為o(1)。雜湊查詢的平均查詢長度取決於哪些因素呢?1.雜湊函式是否均勻。2.處理衝突的方法。3.雜湊表的裝填因子α=填入表中的記錄個數/雜湊表長度。α標誌雜湊表的裝滿的程度.

雜湊表概述

基本概念 通過記錄的儲存位置和它的關鍵字之間建立乙個確定的對應關係f以及處理衝突的方法,使得每個關鍵字和結構中乙個唯一的位置相對應。這樣對於關鍵字k根據對應關係f,就可以得到儲存位置f k 稱這種對應關係f為雜湊函式。與二叉樹不同,雜湊表中儲存的資料是無序的,對於查詢任意資料高效,二叉樹查詢某一範圍...

雜湊表概述

本文對雜湊表進行大體上的概述和分析,如果你之前沒有學過相關知識,可以參考雜湊表以及雜湊表這兩篇文章,有詳細的例子介紹,本文只提供快速回憶和瀏覽。一 什麼是雜湊表?雜湊表本質就是支援隨機查詢的陣列,即可以根據關鍵字快速查詢值的一種陣列,也就是雜湊表。雜湊表實現的關鍵就是雜湊函式,所謂的雜湊函式是一種建...

雜湊表查詢(雜湊表)概述

即通過某個函式 f 使得 儲存位置 f 關鍵字 這樣我們可以通過查詢關鍵字不需要比較就可獲得需要的記錄的儲存位置。這就是新的儲存技術 雜湊技術 雜湊技術是在記錄的儲存位置和它的關鍵字之間建立乙個確定的對應關係 f,使得每個關鍵字 key 對應乙個儲存位置 f key 查詢時,根據這個確定的對應關係找...