資料結構之雜湊(hash)表

2022-01-29 08:39:45 字數 2594 閱讀 9266

最近看php陣列底層結構,用到了雜湊表,所以還是老老實實回去看結構,在這裡去總結一下。

這裡先說一下雜湊(hash)表的定義:雜湊表是一種根據關鍵碼去尋找值的資料對映結構,該結構通過把關鍵碼對映的位置去尋找存放值的地方,說起來可能感覺有點複雜,我想我舉個例子你就會明白了,最典型的的例子就是字典,大家估計小學的時候也用過不少新華字典吧,如果我想要獲取「按」字詳細資訊,我肯定會去根據拼音an去查詢 拼音索引(當然也可以是偏旁索引),我們首先去查an在字典的位置,查了一下得到「安」,結果如下。這過程就是鍵碼對映,在公式裡面,就是通過key去查詢f(key)。其中,按就是關鍵字(key),f()就是字典索引,也就是雜湊函式,查到的頁碼4就是雜湊值。

通過字典查詢資料

但是問題又來了,我們要查的是「按」,而不是「安,但是他們的拼音都是一樣的。也就是通過關鍵字按和關鍵字安可以對映到一樣的字典頁碼4的位置,這就是雜湊衝突(也叫雜湊碰撞),在公式上表達就是key1≠key2,但f(key1)=f(key2)。衝突會給查詢帶來麻煩,你想想,你本來查詢的是「按」,但是卻找到「安」字,你又得向後翻一兩頁,在計算機裡面也是一樣道理的。

但雜湊衝突是無可避免的,為什麼這麼說呢,因為你如果要完全避開這種情況,你只能每個字典去新開乙個頁,然後每個字在索引裡面都有對應的頁碼,這就可以避免衝突。但是會導致空間增大(每個字都有一頁)。

既然無法避免,就只能儘量減少衝突帶來的損失,而乙個好的雜湊函式需要有以下特點:

1.盡量使關鍵字對應的記錄均勻分配在雜湊表裡面(比如說某廠商賣30棟房子,均勻劃分abc3個區域,如果你劃分a區域1個房子,b區域1個房子,c區域28個房子,有人來查詢c區域的某個房子最壞的情況就是要找28次)。

2.關鍵字極小的變化可以引起雜湊值極大的變化。

比較好的雜湊函式是time33演算法。php的陣列就是把這個作為雜湊函式。

核心的演算法就是如下:

unsigned long hash(const

char*key)

return

hash;

}

1.開發定址法

如果遇到衝突的時候怎麼辦呢?就找hash表剩下空餘的空間,找到空餘的空間然後插入。就像你去商店買東西,發現東西賣光了,怎麼辦呢?找下一家有東西賣的商家買唄。

由於我沒有深入試驗過,所以貼上在書上的解釋:

2.鏈位址法

上面所說的開發定址法的原理是遇到衝突的時候查詢順著原來雜湊位址查詢下乙個空閒位址然後插入,但是也有乙個問題就是如果空間不足,那他無法處理衝突也無法插入資料,因此需要裝填因子(插入資料/空間)<=1。

雜湊表的拉鍊法實現

下面解析一下如何用c++實現鏈位址法。

第一步。

肯定是構建雜湊表。

首先定義鏈結點,以結構體node展示,其中node有三個屬性,乙個是key值,乙個value值,還有乙個是作為鍊錶的指標。還有作為類的雜湊表。

#define hashsize 10typedef unsigned 

intuint

;typedef

struct

nodenode;

class

hashtable;

然後定義雜湊表的構造方法

hashtable::hashtable()

}

第二步。

定義雜湊表的hash演算法,在這裡我使用time33演算法。

uint hashtable::hash(const

char*key)

return hash%hashsize;

}

第三步。

node* hashtable::lookup(const

char*key)

return

null;

}

第四步。

定義乙個插入結點的方法,首先是檢視該key值的結點是否存在,如果存在則更改value值就好,如果不存在,則插入新結點。

bool hashtable::install(const

char* key,const

char*value)

np->value=value;

return

true

;}

由於雜湊表高效的特性,查詢或者插入的情況在大多數情況下可以達到o(1),時間主要花在計算hash上,當然也有最壞的情況就是hash值全都對映到同乙個位址上,這樣雜湊表就會退化成煉表,查詢的時間複雜度變成o(n),但是這種情況比較少,只要不要把hash計算的公式外漏出去並且有人故意攻擊(用興趣的人可以搜一下基於雜湊衝突的拒絕服務攻擊),一般也不會出現這種情況。

雜湊衝突攻擊導致退化成煉表載原始碼

Redis資料結構之雜湊hash

雜湊型別 hash 用於儲存鍵值對結構的資料,值只能是字串 hset 新增資料,返回1或0 hset key field value127.0.0.1 6379 hset user 1 name redis integer 1hmset 批量新增資料 hmset key field1 value1 ...

資料結構之雜湊表(雜湊表)

今天學的是資料結構的雜湊查詢篇,其他的查詢可參見以前的傳送門 以前的查詢都是基於比較關鍵字的基礎上,所以查詢的效率依賴於查詢過程中所進行的比較次數。理想的情況是不經過任何比較,通過計算就能直接得到記錄所在的儲存位址,雜湊查詢 hashed search 是基於上述思想的一種查詢方式。雜湊法又稱為雜湊...

資料結構與演算法 雜湊表(hash)

雜湊表是根據關鍵碼值 key value 而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做雜湊表。給定表m,存在函式f key 對任意給定的關鍵字值key,代入函式後若能得到包含該關鍵字的記錄在表中的位址...