雜湊表那些事

2021-07-08 21:06:11 字數 3464 閱讀 4797

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

給定表m,存在函式f(key),對任意給定的關鍵字值key,代入函式後若能得到包含該關鍵字的記錄在表中的位址,則稱表m為雜湊(hash)表,函式f(key)為雜湊(hash) 函式。

常見情況分析:

若關鍵字為

k,則其值存放在

f(k)

的儲存位置上。由此,不需比較便可直接取得所查記錄。稱這個對應關係

f為雜湊函式,按這個思想建立的表為雜湊表。

對不同的關鍵字可能得到同一雜湊位址,k1

≠k2而

f(k1)=f(k2)這種現象稱為碰撞(英語:collision)。具有相同函式值的關鍵字對該雜湊函式來說稱做同義詞。

綜上所述,根據雜湊函式

f(k)

和處理碰撞的方法將一組關鍵字對映到乙個有限的連續的位址集(區間)上,並以關鍵字在位址集中的「像」作為記錄在表中的儲存位置,這種表便稱為雜湊表,這一對映過程稱為雜湊造表或雜湊,所得的儲存位置稱雜湊位址。

若對於關鍵字集合中的任乙個關鍵字,經雜湊函式映象到位址集合中任何乙個位址的概率是相等的,則稱此類雜湊函式為均勻雜湊函式(uniform hash function),這就是使關鍵字經過雜湊函式得到乙個「隨機的位址」,從而減少碰撞。

2方法分析:

雜湊函式能使對乙個資料序列的訪問過程更加迅速有效,通過雜湊函式,資料元素將被更快地定位。

實際工作中需視不同的情況採用不同的雜湊函式,通常考慮的因素有:

·計算雜湊函式所需時間

· 關鍵字的長度

· 雜湊表的大小

· 關鍵字的分布情況

· 記錄的查詢頻率

1. 直接定址法:取關鍵字或關鍵字的某個線性函式值為雜湊位址。即h(key)=key或h(key) = a·key + b,其中a和b為常數(這種雜湊函式叫做自身函式)。若其中h(key)中已經有值了,就往下乙個找,直到h(key)中沒有值了,就放進去。

2. 數字分析法:分析一組資料,比如一組員工的出生年月日,這時我們發現出生年月日的前幾位數字大體相同,這樣的話,出現衝突的機率就會很大,但是我們發現年月日的後幾位表示月份和具體日期的數字差別很大,如果用後面的數字來構成雜湊位址,則衝突的機率會明顯降低。因此數字分析法就是找出數字的規律,盡可能利用這些資料來構造衝突機率較低的雜湊位址。

3. 平方取中法:當無法確定關鍵字中哪幾位分布較均勻時,可以先求出關鍵字的平方值,然後按需要取平方值的中間幾位作為雜湊位址。這是因為:平方後中間幾位和關鍵字中每一位都相關,故不同關鍵字會以較高的概率產生不同的雜湊位址。

例:我們把英文本母在字母表中的位置序號作為該英文本母的內部編碼。例如k的內部編碼為11,e的內部編碼為05,y的內部編碼為25,a的內部編碼為01, b的內部編碼為02。由此組成關鍵字「keya」的內部**為11052501,同理我們可以得到關鍵字「kyab」、「akey」、「bkey」的內部編碼。之後對關鍵字進行平方運算後,取出第7到第9位作為該關鍵字雜湊位址,如下圖所示

關鍵字內部編碼

內部編碼的平方值

h(k)關鍵字的雜湊位址

keya

11050201

122157778355001

778kyab

11250102

126564795010404

795akey

01110525

001233265775625

265bkey

02110525

004454315775625

315

4. 摺疊法:將關鍵字分割成位數相同的幾部分,最後一部分位數可以不同,然後取這幾部分的疊加和(去除進製)作為雜湊位址。數字疊加可以有移位疊加和間界疊加兩種方法。移位疊加是將分割後的每一部分的最低位對齊,然後相加;間界疊加是從一端向另一端沿分割界來回摺疊,然後對齊相加。

5. 隨機數法:選擇一隨機函式,取關鍵字的隨機值作為雜湊位址,通常用於關鍵字長度不同的場合。

6. 除留餘數法:取關鍵字被某個不大於雜湊表表長m的數p除后所得的餘數為雜湊位址。即 h(key) = key mod p,p<=m。不僅可以對關鍵字直接取模,也可在摺疊、平方取中等運算之後取模。對p的選擇很重要,一般取素數或m,若p選的不好,容易產生同義詞。

3處理碰撞方法:

如果兩個同學分別叫 劉麗 劉蘭,當加入劉蘭時,位址24發生了衝突,我們可以以某種規律使用其它的儲存位置,如果選擇的乙個其它位置仍有衝突,則再選下乙個,直到找到沒有衝突的位置。選擇其它位置的方法有:

1、開放定址法

hi=(h(key)+di) mod m i=1,2,...,k(k<=m-1)

其中m為表長,di為增量序列

如果di值可能為1,2,3,...m-1,稱線性探測再雜湊。

如果di取值可能為1,-1,2,-2,4,-4,9,-9,16,-16,...k*k,-k*k(k<=m/2)

稱二次探測再雜湊。

如果di取值可能為偽隨機數列。稱偽隨機探測再雜湊。

例:在長度為11的雜湊表中已填有關鍵字分別為17,60,29的記錄,現有第四個記錄,其關鍵字為38,由雜湊函式得到位址為5,若用線性探測再雜湊,如下:

2、再雜湊法

當發生衝突時,使用第二個、第三個、雜湊函式計算位址,直到無衝突時。缺點:計算時間增加。

3、鏈位址法

將所有關鍵字為同義詞的記錄儲存在同一線性鍊錶中。

4、建立乙個公共溢位區

假設雜湊函式的值域為[0,m-1],則設向量hashtable[0..m-1]為基本表,另外設立儲存空間向量overtable[0..v]用以儲存發生衝突的記錄。

4綜述優缺點:

對雜湊表的使用者一一人來說,這是一瞬間的事。雜湊表運算得非常,在電腦程式中,如果需要在一秒種內查詢上千條記錄通常使用雜湊表(例如拼寫檢查器)雜湊表的速度明顯比樹快,樹的操作通常需要o(n)的時間級。雜湊表不僅速度快,程式設計實現也相對容易。

雜湊表也有一些缺點它是基於陣列的,陣列建立後難於擴充套件某些雜湊表被基本填滿時,效能下降得非常嚴重,所以程式雖必須要清楚表中將要儲存多少資料(或者準備好定期地把資料轉移到更大的雜湊表中,這是個費時的過程)。

而且,也沒有一種簡便的方法可以以任何一種順序〔例如從小到大〕遍歷表中資料項。如果需要這種能力,就只能選擇其他資料結構。

然而如果不需要有序遍歷資料,井且可以提前**資料量的大小。那麼雜湊表在速度和易用性方面是無與倫比的。

Python鍊錶那些事

總結一下鍊錶相關的操作技巧,直接上 coding utf 8 class node object 節點類,記錄值和下一節點指標 def init self,value,nt node self.value value self.nt node nt node def show chain f nod...

關於分庫分表那些事

1 為什麼要分庫分表 設計高併發系統的時候,資料庫層面該如何設計 有哪些分庫分表中介軟體?不同的分庫分表中介軟體都有什麼優點和缺點?如何對資料庫如何進行垂直拆分或水平拆分的?1.2 分表 2 分庫分表的中介軟體 2 mycat proxy 3 垂直和水平拆分 3.2 垂直拆分 3.3 range和h...

那些人,那些事

很久沒有整理一下自己的思緒,聽著熟悉的歌,那歌聲會讓我想起那些人,那些事.乙個標點,乙個符號,乙個個早已在歲月深處冰封的眼神,一段沒有伴侶的歸途。一直以來我都認為我的人生就是這樣,平平淡淡,安安靜靜,波瀾不驚地在歲月的 眼角劃過,不留絲毫痕跡。現在看來,原來我寫的東西在很大程度上是是在滿足自己的某種...