資料結構之二(hash)

2021-06-18 23:59:18 字數 3682 閱讀 6648

hash表

hash表作為一種動態集合資料結構,一般只支援:插入、查詢、刪除操作;而且每個操作的時間複雜度一般控制在o(1)內。

hash表是普通陣列的一種推廣。因為陣列可以在直接通過下標來定位要查詢的元素,時間為o(1)。因此hash表目標也是使用一些技術,以達到可以在o(1)的時間內完成操作。(嚴格來說時間是和裝載因子a相關的)

hash的方法。

1.        直接定址法

前提:關鍵字的全域u比較小;且無重複關鍵字。

方法:關鍵字的全域為。m不是太大,或者可以不考慮記憶體限制;則使用乙個陣列t[0,m-1],每乙個槽代表乙個關鍵字,如果沒有關鍵字對應到槽k,則t[k] = null。

缺點

關鍵字的全域不能太大;

如果實際關鍵字的數量和關鍵字的全域的數量相比,比較小時,則分配的t有些浪費空間。

2.        hash表

為了解決直接定址的缺點,從而產生hash表。

hash表的空間為實際關鍵字的數量階的,o(|k|);與直接定址比缺點在於查詢時間o(1)為平均時間,而直接定址最壞情況也為o(1).

方法:hash表使用乙個hash函式h,以key為引數來計算儲存位置。hash函式h為關鍵字全域u到儲存域m的對映。一般u都比m大,以便達到降低儲存空間的目的,因此對映不為單射。由此,兩個key可能對映到同乙個位置,這時稱為發生碰撞。

3.解決碰撞的方法

把值相同的元素用乙個鍊錶來表示。插入在鍊錶的頭部插入。

裝載因子:裝載因子為hash表中每乙個槽平均存放的元素個數。可以大於、小於、等於1。

簡單一直雜湊:所有元素均勻雜湊到hash表的m個槽位,而且與已經雜湊的情況無關。

缺點:最壞情況下雜湊到乙個槽,這時相對於鍊錶。

時間:裝載因子為a的簡單一直雜湊,則查詢(成功、失敗)的平均時間為o(1+a)。

結果的計算,失敗要找到尾部;成功則需要使用指示隨機變數來計算。

從這個結果可知,如果hash表的槽位數和存放的元素為同階的,即n=o(m)。從而a=n/m=o(1),則hash表的查詢為o(1)的。

3.2.       開放定址法

在插入的過程中,如果有衝突,則會繼續查詢,直到找到乙個空的槽位為止。

探測:衝突時,查詢空槽的過程稱為探測。

與普通hash比,探測需要探測號,探測了幾次。因此比一般的hash多乙個引數。

而且如果表有空槽,則一定會探測到。

因此:h(k,i)對每乙個k來說,h(k,0),h(k,1),…,h(k,m-1)必須為0,1,….,m-1的乙個排列。否則某個位置就不能被探測到。

探測方法

3.2.1.       線性探測

線性探測中,有乙個輔助雜湊函式。或者稱為h(k,0)。

h(k,i)=(h(k,0)+i) mod m

即第一次探測為h(k,0),如果非空,則找h(k,0)+1,直到找到空位置。

缺點:存在稱為一次群集的問題,如果對於不同的k1,k2,如果h(k1,0)和h(k2,0)相同,則所有的探測順序都相同。即隨著時間的推移,連續的槽被占用的情況會增加,從而查詢也會增加開銷。

3.2.2.       二次探測

二次探測是使用二次函式來做探測。也有乙個輔助雜湊函式。或者稱為h(k,0)。

h(k,i)=(h(k,0)+c1*i+c2*i^2) mod m

c1,c2為輔助常數。初始探測也為h(k,0)。之後的探測不是線性的查詢空槽,而是有偏移量的查詢空槽偏移量為探測次數的二次函式。

缺點

和線性探測相同,也有群聚的現象。對於不同的k1,k2,如果h(k1,0)和h(k2,0)相同,則後續的探測都會相同。因此也會產生群聚,這種群聚稱為二次群聚

另外,為了提高hash表的利用率,c1,c2,m的選擇有一些限制。

3.2.3.       雙重雜湊(二次hash)

雙重雜湊使用兩個輔助函式來進行雜湊計算。h1(k),h2(k)。

h(k,i)=(h1(k)+i*h2(k)) mod m

為了探測到整個表,h2(k)有一些限制。一種方法是取m為2的冪次,並使得h2只生成奇數。或者取m為質數,h2產生的數都比m小。

通常,雙重雜湊的探測序列有o(m^2)種順序,比一次和二次探測的o(m)種順序多,從而與一致雜湊比較接近。

3.2.4.       開放定址的複雜度分析

首先開放定址的裝載因此a<=1。

開放定址一般假設為一致雜湊。

查詢不成功:的次數期望為1/(1-a)。證明使用事件序列,且都探測失敗。hash表半滿,則為2次;為90%滿,則次數為10次。因此如果太滿,則查詢失敗的次數將急劇增加。

插入元素:需要的探測次數的期望為1/(1-a)。因為插入需要做一次查詢不成功的探測。

查詢成功:的次數期望至多為(1/a)*ln(1/(1-a))。比如:hash表為半滿的,則查詢成功的期望為1.3次左右;hash表為90%滿的,則期望為2.5次左右。

4.        hash函式

比較好的雜湊函式是盡可能的滿足簡單一直雜湊的條件。

4.1.       除法雜湊

使關鍵字對m取餘。

選擇的限制:m應該選擇質數,且不要接近為2的冪次的數,或10的冪次。

不為2的冪次是因為,k對2的冪次取餘相當於取k的低位,而將高位忽略了。

不為2的冪次減一(如:2^p-1)是因為,如果字元按2^p為基數來解釋,則字元相同,但順序不同的字串可以對映到同樣的鍵。

4.2.       乘法雜湊

選取固定的關鍵字0h(k)=[m*(kamod1)]----1式

含義為關鍵字乘上a後取小數部分,再與m相乘(即hash表的長度),取整即可。

乘法的優點是對m沒有要求,因此一般選擇m為2的冪次。

特別:計算機乙個位元組為w個bit位。hash表的表長m=2^r。則1式可表示為

h[k] = ((a*k)mod(2^w))>>(w-r)----2式

a一般取值在(2^(w-1),2^w)之間。

一般取1式中的a接近**分割值。

在2式中,w,r一般為事先已知(w為位元組位數,r為hash表的位數),從而只需要選擇a值即可將h確定下來。

2式可以理解為:將a表示為二進位制的分數,k乘上a後取小數部分,並取小數部分的最高r位(即向右移動w-r位的整數)。

也可以理解為:將圓圈等分為m份,即hash表的長度;hash函式為在圓上轉動k次,每次轉動a個格仔,最終停下來的地方即為hash函式的結果值。

1式和2式中只有乘法和對2的冪次取餘,對2的冪次取餘屬於移位操作,因此比除法要節約時間。

資料結構 hash

雜湊表 hash table,也叫雜湊表 是根據鍵 key 而直接訪問在記憶體儲存位置的資料結構。分為兩個步驟 hash函式 通過乙個關於鍵值的hash函式,得到所查詢的資料對映到表中乙個位置。訪問資料 不同的key 經過hash函式 可能計算得到相同的輸出。此時叫做衝突,衝突的資料又成乙個表。一般...

資料結構 資料結構之二分查詢

先上 二分查詢,陣列必須為有序的 int binarysearch int key,int a,int length return 1 該函式接受乙個整數鍵和乙個已經有序的int陣列及陣列的大小作為引數。如果該鍵存在於陣列中則返回它的索引,否則返回 1.演算法使用兩個變數lo和hi,並保證如果鍵在陣...

資料結構之hash

hash表 雜湊表 hash table,也叫雜湊表 是根據key而直接進行訪問的資料結構。也就是說,它通過把key對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做雜湊表。以資料中每個元素的關鍵字k為自變數,通過雜湊函式h k 計算出函式值,以該函式值作為...