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
for i:=0 to p-1 do
a[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) do
inc(i);
//當這個迴圈停下來時,要麼找到乙個空的儲存單元,要麼找到這個元
//素儲存的單元,要麼表已經滿了
locate:=(orig+i) mod s;
end;
插入元素
[cpp]view plain
copy
procedure insert(x:longint);
var posi:integer;
begin
posi:=locate(x); //定位函式的返回值
if a[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);
if a[posi]=x then member:=true
else member:=false;
end;
這些就是建立在雜湊表上的常用基本運算。
雜湊表工作原理
1.引言 雜湊表 hash table 的應用近兩年才在noi中出現,作為一種高效的資料結構,它正在競賽中發揮著越來越重要的作用。雜湊表最大的優點,就是把資料的儲存和查詢消耗的時間大大降低,幾乎可以看成是常數時間 而代價僅僅是消耗比較多的記憶體。然而在當前可利用記憶體越來越多的情況下,用空間換時間的...
電流錶工作原理
電流錶是根據通電導體在 磁場中受磁場力的作用而製成的。電流錶內部有一永磁體,在極間產生磁場,在磁場中有乙個線圈,線圈兩端各有乙個螺旋彈簧,彈簧各連線電流錶的乙個接線柱,在彈簧與線圈間由乙個轉軸連線,在轉軸相對於電流錶的前端,有乙個指標。當有電流通過時,電流沿彈簧 轉軸通過磁場,電流切磁感線,所以受磁...
雜湊工作原理與應用
參考 我們使用乙個下標範圍比較大的陣列來儲存元素。可以設計乙個函式 雜湊函式,也叫做雜湊函式 使得每個元素的關鍵字都與乙個函式值 即陣列下標 相對應,於是用這個陣列單元來儲存這個元素 也可以簡單的理解為,按照關鍵字為每一 個元素 分類 然後將這個元素儲存在相應 類 所對應的地方。但是,不能夠保證每個...