雜湊表工作原理

2021-06-25 18:21:56 字數 2634 閱讀 8957

1. 引言 

雜湊表(hash table)的應用近兩年才在noi中出現,作為一種高效的資料結構,它正在競賽中發揮著越來越重要的作用。 

雜湊表最大的優點,就是把資料的儲存和查詢消耗的時間大大降低,幾乎可以看成是常數時間;而代價僅僅是消耗比較多的記憶體。然而在當前可利用記憶體越來越多的情況下,用空間換時間的做法是值得的。另外,編碼比較容易也是它的特點之一。 

雜湊表又叫做雜湊表,分為「開雜湊」 和「閉雜湊」。考慮到競賽時多數人通常避免使用動態儲存結構,本文中的「雜湊表」僅指「閉雜湊」,關於其他方面讀者可參閱其他書籍。

2. 基礎操作 

2.1 基本原理 

我們使用乙個下標範圍比較大的陣列來儲存元素。可以設計乙個函式(雜湊函式, 也叫做雜湊函式),使得每個元素的關鍵字都與乙個函式值(即陣列下標)相對應,於是用這個陣列單元來儲存這個元素;也可以簡單的理解為,按照關鍵字為每一 個元素「分類」,然後將這個元素儲存在相應「類」所對應的地方。 

但是,不能夠保證每個元素的關鍵字與函式值是一一對應的,因此極有可能出現對於不同的元素,卻計算出了相同的函式值,這樣就產生了「衝突」,換句話說,就是把不同的元素分在了相同的「類」之中。後面我們將看到一種解決「衝突」的簡便做法。 

總的來說,「直接定址」與「解決衝突」是雜湊表的兩大特點。 

2.2 函式構造 

建構函式的常用方法(下面為了敘述簡潔,設 h(k) 表示關鍵字為 k 的元素所對應的函式值): 

a) 除餘法: 

選擇乙個適當的正整數 p ,令 h(k ) = k mod p ,這裡, p 如果選取的是比較大的素數,效果比較好。而且此法非常容易實現,因此是最常用的方法。 

b) 數字選擇法: 

如果關鍵字的位數比較多,超過長整型範圍而無法直接運算,可以選擇其中數字分布比較均勻的若干位,所組成的新的值作為關鍵字或者直接作為函式值。 

2.3 衝突處理 

線性重新雜湊技術易於實現且可以較好的達到目的。令陣列元素個數為 s ,則當 h(k) 已經儲存了元素的時候,依次探查 (h(k)+i) mod s , i=1,2,3…… ,直到找到空的儲存單元為止(或者從頭到尾掃瞄一圈仍未發現空單元,這就是雜湊表已經滿了,發生了錯誤。當然這是可以通過擴大陣列範圍避免的)。 

2.4 支援運算 

雜湊表支援的運算主要有:初始化(makenull)、雜湊函式值的運算(h(x))、插入元素(insert)、查詢元素(member)。 設插入的元素的關鍵字為 x ,a 為儲存的陣列。 初始化比較容易,例如 :

[cpp] view plain

copy

const

empty=maxlongint; 

// 用非常大的整數代表這個位置沒有儲存元素

p=9997; // 表的大小

procedure makenull;  

var i:integer;  

begin  

fori:=0 to p-1 

doa[i]:=empty;  

end;   

雜湊函式值的運算根據函式的不同而變化,例如除餘法的乙個例子: 

[cpp] view plain

copy

function h(x:longint):integer;  

begin  

h:= x mod p;  

end;   

我們注意到,插入和查詢首先都需要對這個元素定位,即如果這個元素若存在,它應該儲存在什麼位置,因此加入乙個定位的函式 locate 

[cpp] view plain

copy

function locate(x:longint):integer;  

var orig,i:integer;  

begin  

orig:=h(x);  

i:=0;  

while

(ix)and(a[(orig+i)mod s]<>empty) 

doinc(i);  

//當這個迴圈停下來時,要麼找到乙個空的儲存單元,要麼找到這個元

//素儲存的單元,要麼表已經滿了

locate:=(orig+i) mod s;  

end;   

插入元素 

[cpp] view plain

copy

procedure insert(x:longint);  

var posi:integer;  

begin  

posi:=locate(x); //定位函式的返回值

ifa[posi]=empty then a[posi]:=x  

else

error; 

//error 即為發生了錯誤,當然這是可以避免的

end;   

查詢元素是否已經在表中 

[cpp] view plain

copy

procedure member(x:longint):boolean;  

var posi:integer;  

begin  

posi:=locate(x);  

ifa[posi]=x then member:=

true

else

member:=

false

;  end;   

這些就是建立在雜湊表上的常用基本運算。

雜湊表工作原理

1.引言 雜湊表 hash table 的應用近兩年才在noi中出現,作為一種高效的資料結構,它正在競賽中發揮著越來越重要的作用。雜湊表最大的優點,就是把資料的儲存和查詢消耗的時間大大降低,幾乎可以看成是常數時間 而代價僅僅是消耗比較多的記憶體。然而在當前可利用記憶體越來越多的情況下,用空間換時間的...

電流錶工作原理

電流錶是根據通電導體在 磁場中受磁場力的作用而製成的。電流錶內部有一永磁體,在極間產生磁場,在磁場中有乙個線圈,線圈兩端各有乙個螺旋彈簧,彈簧各連線電流錶的乙個接線柱,在彈簧與線圈間由乙個轉軸連線,在轉軸相對於電流錶的前端,有乙個指標。當有電流通過時,電流沿彈簧 轉軸通過磁場,電流切磁感線,所以受磁...

雜湊工作原理與應用

參考 我們使用乙個下標範圍比較大的陣列來儲存元素。可以設計乙個函式 雜湊函式,也叫做雜湊函式 使得每個元素的關鍵字都與乙個函式值 即陣列下標 相對應,於是用這個陣列單元來儲存這個元素 也可以簡單的理解為,按照關鍵字為每一 個元素 分類 然後將這個元素儲存在相應 類 所對應的地方。但是,不能夠保證每個...