27 雜湊表(雜湊表)查詢

2021-08-16 04:44:09 字數 3263 閱讀 7405

在之前的內容中講述了許多關於查詢的方法,比如說順序表查詢(挨個兒比較);有序表查詢(二分法查詢)。在這裡將介紹一種用於查詢的儲存技術,即雜湊表(或稱為雜湊表)。

在雜湊表中,記錄的儲存位置 = f (關鍵字),通過查詢關鍵字的儲存位置即可,不用進行比較。雜湊技術是在記錄的儲存位置和它的關鍵字之間建立乙個明確的對應關係f 函式,使得每個關鍵字 key 對應乙個儲存位置 f(key) 且這個位置是唯一的。這裡我們將這種對應關係 f 稱為雜湊函式,又稱為雜湊(hash)函式。採用雜湊技術將記錄儲存在一塊連續的儲存空間中,這塊連續儲存空間稱為雜湊表或雜湊表(hash table)。

當儲存記錄時,通過雜湊函式計算出記錄的雜湊位址;當查詢記錄時,我們通過同樣的是雜湊函式計算記錄的雜湊位址,並按此雜湊位址訪問該記錄。雜湊技術即使一種儲存方法,也是一種查詢方法;雜湊技術之間沒有關係,只有關鍵字和函式之間有關係,所以雜湊技術是一種面向查詢的儲存技術

缺點是會存在關鍵字重複的問題,比如說男女為關鍵字的時候就不合適了。同樣不適合查詢範圍的,比如說查詢18-20歲之間的同學。雜湊表技術對於1對1的查詢是適合的。

「好的雜湊函式 = 計算簡單 + 分布均勻」。其中計算簡單指的是雜湊函式的計算時間不應該超過其他查詢技術與關鍵字比較的時間,而分布均勻指的是雜湊位址分布均勻。

即使用關鍵字本身作為函式值,即f(key) = key。假如有乙個從1到100歲的人口數字統計表,其中,年齡作為關鍵字,雜湊函式取關鍵字自身。

如,下圖所示

所以直接定值法是取關鍵字的某個線性函式值為雜湊位址,即 f(key) = a*key + b。其優點是簡單、均勻,不會產生衝突;但缺點是需要知道關鍵字的分布情況,希望數值是連續的。

數字分析法通常適合處理關鍵字位數比較大的情況,例如我們現在要儲存某家公司員工登記表,如果用手機號作為關鍵字,那麼我們發現抽取後面的四位數字作為雜湊位址是不錯的選擇,如下圖所示

平方取中法是將關鍵字平方之後取中間若干位數字作為雜湊位址。這種方法適用於不知道關鍵字的分布,且數值的位數又不是很大的情況。

摺疊法是將關鍵字從左到右分割成位數相等的幾部分,然後將這幾部分疊加求和,並按雜湊表表長取後幾位作為雜湊位址。

此方法為最常用的構造雜湊函式方法,對於雜湊表長為m的雜湊函式計算公式為:

f(key) = key mod p(p<=m)

事實上,這個方法不僅可以對關鍵字直接取模,也可以通過摺疊、平方取中後再取模。例如下表,我們對有12個記錄的關鍵字構造雜湊表時,就可以用f(key) = key mod 12的方法。

p的選擇是關鍵,如果對於這個**的關鍵字,p還選擇12的話,那得到的情況未免也太糟糕了:

p的選擇很重要,如果我們把p改為11,那結果就另當別論啦:

當然在上述的這種情況中仍然是有衝突的情況,對於這種情況在後面中會介紹解決的方法。

選擇乙個隨機數,取關鍵字的隨機函式值為它的雜湊位址。

f(key) = random(key)。

這裡的random是隨機函式,當關鍵字的長度不等時,採用這個方法構造雜湊函式是比較合適的。

(1) 計算雜湊位址所需的時間;

(2) 關鍵字的長度;

(3) 列表的大小;

(4) 關鍵字的分布情況;

(5) 記錄查詢的頻率。

fi(key) = (f(key)+di) mod m (di=1,2,…,m-1)

例:假設關鍵字集合為,使用除留餘數法(m=12)求雜湊表

也可以修改di的取值方式,例如使用平方運算來盡量解決堆積問題:

fi(key) = (f(key)+di) mod m (di=1²,-1²,2²,-2²…,q²,-q²,q<=m/1)

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

fi(key) = (f(key)+di) mod m (di是由乙個隨機函式獲得的數列)

同時準備多個雜湊函式,當第乙個雜湊函式發生衝突的時候可以用備選的雜湊函式進行計算。

例:假設關鍵字集合為,同樣使用除留餘數法求雜湊表,如下圖所示

例:假設關鍵字集合為,同樣使用除留餘數法求雜湊表,如下圖所示

沒有衝突的元素放在左邊的表,有衝突的元素,將多餘的元素放在右邊的那個表。

在這裡採用除留餘數法構造雜湊函式,**中還包括雜湊表的結構定義,雜湊表的初始化,插入關鍵字和查詢關鍵字

#define hashsize 12

#define nullkey -32768

// 定義乙個雜湊表的結構

typedef

struct

hashtable;

// 初始化雜湊表

int inithashtable(hashtable *h)

for( i=0; i < hashsize; i++ )

return0;}

// 使用除留餘數法

int hash(int key)

// 插入關鍵字到雜湊表

void inserthash(hashtable *h, int key)

h->elem[addr] = key;

}// 雜湊表查詢關鍵字

int searchhash(hashtable h, int key, int *addr)

}return

0;}

查詢 雜湊表查詢(雜湊表)

1 雜湊表查詢定義 雜湊技術是在記錄的儲存位置和它的關鍵字之間建立乙個確定的對應關係f,使得每個關鍵字key對應乙個儲存位置f key 查詢時,根據這個確定的對應關係找到給定值key的對映f key 若查詢集合中存在這個記錄,則必定在f key 的位置上。採用雜湊技術將記錄儲存在一塊連續的儲存空間中...

雜湊表(雜湊表)查詢

雜湊技術是在記錄的儲存位置和它的關鍵字之間建立起乙個確定的對應關係f,使每個關鍵字key對應乙個儲存位置f key f為雜湊函式,又稱雜湊函式。採用雜湊技術將記錄儲存在一塊連續的儲存空間中,這塊連續的儲存空間成為雜湊表 雜湊表。直接用key值的某個線性函式當位址。f key a key b 簡單,不...

雜湊表 雜湊表 查詢

直接定址法 數字分析法 平方取中法 平方取中法是將關鍵字平方之後取中間若干位數字作為雜湊位址。摺疊法摺疊法是將關鍵字從左到右分割成位數相等的幾部分,然後將這幾部分疊加求和,並按雜湊表表長取後幾體作為雜湊位址。除留餘數法 隨機數法 選擇乙個隨機數,取關鍵字的隨機函式值為它的雜湊位址。即 f key r...