雜湊表 雜湊表 C語言簡單實現

2021-10-10 19:32:57 字數 4960 閱讀 6173

本文參考自《大話資料結構》

通過某個函式f計算出記錄的儲存位置,而不需要通過比較,這就是一種新的儲存技術——雜湊技術。

雜湊技術是在記錄的儲存位置和它的關鍵字之間建立乙個確定的對應關係f,使得每個關鍵字key對應乙個儲存位置f(key)。在查詢時,根據這個確定的對應關係找到給定值key的對映f(key),若查詢集合中存在這個記錄,則必定在f(key)的位置上。

我們把這種對應關係f稱為雜湊函式,又稱為雜湊函式。按照這個思路,採用雜湊技術將記錄儲存在一塊連續的儲存空間中,這塊連續儲存空間稱為雜湊表或雜湊表

在儲存時,通過雜湊函式計算記錄的雜湊位址,並按此雜湊位址儲存該記錄;

當查詢記錄時,我們通過同樣的雜湊函式計算記錄的雜湊位址,按此雜湊位址訪問該記錄。

雜湊技術既是一種儲存方法,也是一種查詢方法。但它與線性表、樹、圖等結構不同,前面幾種結構,資料元素之間都存在某種邏輯關係,可以用連線圖示表示出來,但是雜湊技術的記錄之間不存在什麼邏輯關係,它只與關鍵字有關聯。因此,雜湊主要是面相查詢的儲存結構。

雜湊技術最適合的求解問題是查詢與給定值相等的記錄

雜湊表不適合範圍查詢,還有乙個關鍵字對應多個記錄的情況

取關鍵字的某個線性函式值為雜湊位址,即f(key) = a*key+b(a、b為常數)

使用關鍵字的一部分來計算雜湊儲存位置的方法,比如操作手機號碼的後幾位。如果事先知道關鍵字的分布且關鍵字的若干位分布較均勻,就可以考慮用這個方法

比如關鍵字1234,平方就是1522756,取中間的3位就是227。適用不知道關鍵字的分布,而位數又不是很大的情況

摺疊法師將關鍵字從左到右分割成位數相等的幾部分(最後一部分位數不夠時可以短些),然後將這幾部分疊加求和,並按雜湊表表長,取後幾位作為雜湊位址。有時可能還不夠保證分布均勻,不妨從一端向另一端來回摺疊後對齊想加。摺疊法事先不需要知道關鍵字的分布,適合關鍵字位數較多的情況

這是最常用的構造雜湊函式的方法。對於雜湊表長為m的雜湊函式公式為f(key)=key mod p(p<=m),mod是取模(求餘數)。事實上,這方法不僅可以對關鍵字直接取模,也可以在摺疊,平方去中後再取模。本方法的關鍵就在於要選擇合適的p。

若雜湊表表長為m,通常p為小於或等於表長(最好接近m)的最小質數或不包含小於20質因子的合數

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

對於字串如何處理?字串或者中文字元,可以轉換成ascii碼或者unicode碼等。

使用不同的雜湊函式考慮的因素:

計算雜湊位址所需的時間

關鍵字的長度

雜湊表的大小

關鍵字的分布情況

記錄查詢的頻率

開放定址法就是一旦發生了衝突,就去尋找下乙個空的雜湊位址,只要雜湊表足夠大,空的雜湊位址總能找到,並將記錄存入。

公式fi(key) = (f(key)+di) mod m (di=1,2,3,...,m-1)

這種解決衝突的開放定址法稱為線性探測法。這種方法有乙個問題,就是會有本來不是同義詞卻需要爭奪乙個位址的情況,我們稱這種現象為堆積

改進:增加平方運算的目的是為了不讓關鍵字都聚集在某一塊區域,我們稱這種方法為二次探測法fi(key)=(f(key)+di) mod m (di=1^2,-1^2,2^2,-2^2,...,q^2,-q^2,q<=m/2)

還有一種方法,在衝突時,對於位移量di採用隨機函式計算得到,我們稱之為隨機探測法。這裡的隨機其實是偽隨機數,即i我們設定隨機種子相同,則不斷呼叫隨機函式可以生成不會重複的數列,在查詢的時候,使用同樣的隨機種子,它每次得到的數列是相同的,相同的di,所以查詢的時候可以得到相同的雜湊位址。

fi(key) = (f(key)+di) mod m (di是乙個隨機數列),總之,只要雜湊表未填滿,總能找到不發生衝突的位址。

可以事先準備多個雜湊函式fi(key) = rhi(key) (i=1,2,...,k),當發生衝突了,就換乙個雜湊函式計算,這種方法能夠使得關鍵字不產生聚集,但是也會相應地增加運算時間。

鏈位址法師將關鍵字為同義詞的記錄儲存在乙個單鏈表中,我們稱這種表為同義詞子表,在雜湊表中只儲存所有同義詞子表的頭指標。這樣做的優點是不會找不到地方來儲存衝突的同義詞,但是缺點是查詢時需要遍歷單鏈表,效能上會損耗

公共溢位區結構和基本表一樣,就是衝突的資料儲存在溢位區,查詢的時候先在基本錶比對,如果不是,則到溢位區順序查詢。對於衝突少的資料來說,查詢效能還是很高的。

#define success 1

#define unsuccess 0

#define hashsize 12

//定義雜湊表長為陣列的長度

#define nullkey -32768

typedef

struct

hashtable;

int m =0;

//雜湊表表長,全域性變數

status inithashtable

(hashtable *h)

int

hash

(int key)

/* 插入關鍵字進雜湊表 */

void

inserthash

(hashtable *h,

int key)

**中插入關鍵字時,首先算出雜湊位址,如果當前位址不為空關鍵字,則說明有衝突。此時我們應用開放定址法的線性探測進行重新定址,此處也可更改為鏈位址法等其他解決衝突的方法。

/* 雜湊表查詢關鍵字 */

status searchhash

(hashtable h,

int key,

int*addr)

return success;

}

如果沒有衝突,雜湊查詢是所有查詢中效率最高的,因為它的時間複雜度為o(1)。可惜,衝突是存在的,所以在實際應用中,衝突是不可避免的,那麼雜湊查詢的平均查詢長度取決於哪些因素呢?

雜湊函式是否均勻。由於不同的雜湊函式對同一組隨機的關鍵字,產生衝突的可能性是相同的,因此我們可以不考慮它對平均查詢長度的影響;

處理衝突的方法。相同的關鍵字、相同的雜湊函式,但處理衝突的方法不同,會使得平均查詢長度不同。比如線性探測處理衝突可能會產生堆積,顯然沒有二次探測法好,而鏈位址法處理衝突不會產生任何堆積,因而具有更佳的平均查詢效能;

雜湊表的填裝因子。填裝因子a=填入表中的記錄個數/雜湊表長度。a標誌著雜湊表的裝滿程度。當填入表中的記錄越多,a就越大,產生衝突的可能性就越大。也就是說,雜湊表的平均查詢長度取決於填裝因子,而不是取決於查詢集合中的記錄個數。

不管記錄個數n有多大,我們總可以選擇乙個合適的填裝因子以便將平均查詢長度限定在乙個範圍內,此時我們雜湊查詢的時間複雜度就真的是o(1)。為了做到這一點,通常我們都是將雜湊表的空間設定得比查詢集合大,此時雖然浪費了一定的空間,但換來的是查詢效率的大大提公升,還是值得的。

#include

#include

#include

#define hashsize 12

//定義雜湊表長為陣列的長度

#define nullkey -32768

struct hashtable

;int numhash =0;

//雜湊表長,全域性變數

/* 初始化雜湊表 */

void

inithashtable

(hashtable* h)

/* 用到的雜湊函式 */

inthash

(int key)

/* 插入關鍵字進雜湊表 */

void

inserthash

(hashtable* h,

int key)

/* 查詢關鍵字 */

bool searchkeyinhash

(hashtable h,

int key,

int* addr)

return true;

}/* 列印雜湊表 */

void

printhashtable

(hashtable h)

intmain()

;inithashtable

(h);

printhashtable

(*h)

;for

(i=0

;i<

10;i++

)inserthash

(h, a[i]);

printhashtable

(*h)

;//查詢if(

searchkeyinhash

(*h,15,

&i))

printf

("找到了!\n");

else

printf

("關鍵字不存在!\n");

雜湊表(雜湊表) C 實現

雜湊函式就是 關鍵字key 到 值value 的對映 value f key value反映的是關鍵字key的儲存位址。直接定址法 f key a key b 例如存放不同出生年份的人口數量,出生年份是關鍵字,那麼可以用直接定址法。直接定址法的優點是簡單均勻,也不會產生衝突 缺點是該方法適合表比較小...

簡單的雜湊表實現 C語言

這是乙個簡單的雜湊表的實現,用c語言做的。先說一下原理。先是有乙個bucket陣列,也就是所謂的桶。雜湊表的特點就是資料與其在表中的位置存在相關性,也就是有關係的,通過資料應該可以計算出其位置。這個雜湊表是用於儲存一些鍵值對 key value 關係的資料,其key也就是其在表中的索引,value是...

簡單雜湊表實現

雜湊表定義 雜湊表又稱雜湊表,是根據關鍵碼值 key value 而直接訪問的資料結構。它通過把關鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式 存放記錄的陣列 叫做雜湊表。雜湊表既有陣列的特點 定址容易 又有鍊錶的特點 方便插入,刪除 雜湊表結構示意圖 下面編寫乙個...