通常我們查詢資料都是通過乙個乙個地比較來進行,有一種方法,要尋找的資料與其在資料集中的位置存在一種對應的關係,通過這種關係就能找到資料的位置。這個對應關係成為雜湊函式(雜湊函式),因此建立的表為雜湊表(雜湊表)。
雜湊查詢是關鍵字與在資料集中的位置一一對應,通過這種對應關係能快速地找到資料,雜湊查詢中雜湊函式的構造和處理衝突的方法尤為重要
雜湊函式的構造
構造雜湊表的前提是要有雜湊函式,並且這個函式盡可能地減小衝突
(1)直接定址法
可以取關鍵字的某個線性函式值為雜湊位址,即
f(key) = a*key + b
這樣的雜湊函式簡單均勻,不會產生衝突,但問題是這需要事先知道關鍵字的分布情況,適合查詢表較小且連續的情況。
(2)數字分析法
該方法在知道關鍵字的情況下,取關鍵字的盡量不重複的幾位值組成雜湊位址。
(3)平方取中法
取關鍵字平方後的中間幾位為雜湊位址
(4)摺疊法
將關鍵字分為位數相等的幾部分,最後一部分的位數可以不等,然後把這幾部分的值(捨去進製)相加作為雜湊位址。
(5)除留餘數法
該方法為最常用的構造雜湊函式方法,對於雜湊表長為m的雜湊函式公式為
f(key) = key mod p (p<=m)
使用除留餘數法的乙個經驗是,若雜湊表表長為m,通常p為小於或等於表長的最小質數或不包含小於20質因子的合數。
實踐證明,當p取小於雜湊表長的最大質數時,函式較好。
(6)隨機數法
選擇乙個隨機函式,取關鍵字的隨機函式值作為雜湊位址。
處理衝突
(1)開發定址法
fi(key) = (f(key)+di) mod m (di=1,2,3...m-1)
用開放定址法解決衝突的做法是:當衝突發生時,使用某種探測技術在雜湊表中形成乙個探測序列,沿此序列逐個單元地查詢,直到找到給定的關鍵字,或者碰到乙個開放的位址(該位址單元為空)為止(若要插入,在探查到開放的位址,則可將帶插入的新節點存入該位址單元)。查詢時探測到開放的位址則表明表中無待查的關鍵字,即查詢失敗。
比如說,我們的關鍵字集合為,表長為12。 我們用雜湊函式f(key) = key mod l2。
計算key = 37時,發現f(37) = 1,此時就與25所在的位置衝突。
接下來22,29,15,47都沒有衝突,正常的存入:
到了 key=48,我們計算得到f(48) = 0,與12所在的0位置衝突了,不要緊,我們f(48) = (f(48)+1) mod 12 = 1,此時又與25所在的位置衝突。於是f(48) = (f(48)+2) mod 12=2,還是衝突……一直到 f(48) = (f(48)+6) mod 12 = 6時,才有空位,機不可失,趕快存入:
我們把這種解決衝突的開放定址法稱為線性探測法。
二次探測法
考慮深一步,如果發生這樣的情況,當最後乙個key=34,f(key)=10,與22所在的位置衝突,可是22後面沒有空位置了,反而它的前面有乙個空位置,儘管可以不斷地求餘數後得到結果,但效率很差。
因此我們可以改進di = 12, -12, 22, -22,……, q2, -q2 (q <= m/2),這樣就等於是可以雙向尋找到可能的空位置。
對於34來說,我們取di即可找到空位置了。另外增加平方運算的目的是為了不讓關鍵字都聚集在某一塊區域。我們稱這種方法為二次探測法。
fi(key) = (f(key)+di) mod m (di = 12, -12, 22, -22,……, q2, -q2, q <= m/2)
隨機探測法
還有一種方法,是在衝突時,對於位移量di採用隨機函式計算得到,我們稱之為隨機探測法。
此時一定會有人問,既然是隨機,那麼查詢的時候不也隨機生成嗎?如何可以獲得相同的位址呢?這是個問題。這裡的隨機其實是偽隨機數。
偽隨機數是說,如果我們設定隨機種子相同,則不斷呼叫隨機函式可以生成不會重複的數列,我們在查詢時,用同樣的隨機種子,它每次得到的數列是相同的,相同的di當然可以得到相同的雜湊位址。
fi(key) = (f(key)+di) mod m (di是乙個隨機數列)
總之,開放定址法只要在雜湊表未填滿時,總是能找到不發生衝突的位址,是我們常用的解決衝突的辦法。
(2) 再雜湊法
再雜湊法是當雜湊位址衝突時,用另外乙個雜湊函式再計算一次,這種方法減少了衝突,但增加了計算的時間。
(3) 鏈位址法
可以的,於是我們就有了鏈位址法。
將所有關鍵字雜湊位址相同的記錄儲存在乙個單鏈表中,我們稱這種表為同義詞子表,在雜湊表中只儲存所有同義詞子表的頭指標。
對於關鍵字集合,我們用12為除數,進行除留餘數法:
此時,已經不存在什麼衝突換址的問題,無論有多少個衝突,都只是在當前位置給單鏈表增加結點的問題。鏈位址法解決衝突的做法是:將所有關鍵字雜湊位址相同的結點鏈結在同乙個單鏈表中。若選定的雜湊表長度為m,則可將雜湊表定義為乙個由m個頭指標組成的指標陣列t[0..m-1]。凡是雜湊位址為i的結點,均插入到以t[i]為頭指標的單鏈表中。t中各分量的初值均應為空指標。在拉鍊法中,裝填因子α可以大於1,但一般均取α≤1。
鏈位址法的優勢是對於可能會造成很多衝突的雜湊函式來說,提供了絕不會出現找不到位址的保障。當然,這也就帶來了查詢時需要遍歷單鏈表的效能損耗,不過效能損耗在很多場合下也不是什麼大問題。
(4) 建立公共溢位區
這種方法的基本思想是:將雜湊表分為基本表和溢位錶兩部分,凡是和基本表發生衝突的元素,一律填入溢位表。
雜湊查詢 資料結構
假定乙個集合為s 集合長度為n 假定選取的雜湊函式為 h k k m 即用元素的 關鍵字k整除以雜湊表的長度m 假定k和m均為正整數,並且m n 取餘數作為儲存該元素的雜湊位址。h 18 18 13 5 h 75 75 13 10 h 60 60 13 8 h 43 43 13 4 h 54 54 ...
雜湊查詢 資料結構
define crt secure no warnings include iostream include stdlib.h include windows.h include iomanip using namespace std define ok 1 define error 0 defin...
資料結構 雜湊查詢
為什麼要用雜湊查詢?什麼是雜湊查詢?解決衝突有哪些方法?如何評估查詢?雜湊函式如何設計?順序查詢 時間複雜度 o n 二分查詢 前提有序 時間複雜度 o logn 二叉搜尋樹 時間複雜度 o h h 是樹高,最好情況 h logn,最差 h n 二叉平衡樹 時間複雜度 o logn 如何資料量很大時...