雜湊表 雜湊表

2021-06-09 16:08:28 字數 4287 閱讀 6484

一、定義 

雜湊表(hash table,也叫雜湊表),是根據關鍵碼值(key value)而直接進行訪問的資料結構。

也就是說,它通過把關鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做雜湊表。

雜湊表的做法其實很簡單,就是把key通過乙個固定的演算法函式既所謂的雜湊函式轉換成乙個整型數字,然後就將該數字對陣列長度進行取餘,取餘結果就當作陣列的下標,將value儲存在以該數字為下標的陣列空間裡。

而當使用雜湊表進行查詢的時候,就是再次使用雜湊函式將key轉換為對應的陣列下標,並定位到該空間獲取value,如此一來,就可以充分利用到陣列的定位效能進行資料定位。

比如:有乙個很大的有序陣列,想要得到位於該陣列第n個位置的值,它的演算法複雜度為o(1)。

雜湊表利用雜湊函式將需要儲存的內容的關鍵值轉換為這個有序陣列中的某個值,在被儲存內容和有序陣列之間建立了對映關係。這樣,下次我們對這個值進行查詢時只要使用同乙個雜湊函式對關鍵值進行轉換,找到這個陣列值 就可以了。

如果還沒有明白是怎麼回事的話,那我們來舉個例子。假設我們要做個儲存結構,需要儲存下來三國中的人物,以及他們的詳細資訊。我們用他們的名字來作為儲存 的關鍵值,例如:劉備,曹操,孫權,關羽,張飛……等等。這個時候我們如果想用一般的方法來查詢這些英雄豪傑,需要遍歷整個儲存空間,如果這些英雄豪傑一 共有n個,那麼這時候的時間演算法複雜度為o(n)。顯然如果n值很大,每次想要找到某個英雄就需要比較長的時間。

此時我們先定義乙個大的有序結構陣列hashvalue[m],用來存放各位英雄豪傑的資訊。然後編寫乙個雜湊函式changetohashvalue (name),函式的具體內容就不細說了,反正這個函式會將這些做為關鍵值的名字轉換為hashvalue[m]中的某個下標值x。然後可以將英雄的資訊 放進hashvalue[x]中去。這樣,可以將所有英雄的資訊儲存起來。當查詢的時候再使用雜湊函式changetohashvalue(name)得 到這個下標值,這樣就很容易得到了這個英雄的資訊。例如:changetohashvalue(劉備)為10,那麼就將劉備儲存到hashvalue [10]裡面。當查詢的時候再次使用changetohashvalue(劉備)得到10,這個時候我們就可以很容易找到劉備的所有資訊。在實際應用中如 果我們想把所有的英雄豪傑都儲存進系統時,需要定義m>n。就是陣列的大小要大於需要儲存的資訊量,所以說雜湊表是乙個以空間換取時間的資料結構。

這個時候問題來了,出現了這種情況changetohashvalue(關羽)和changetohashvalue(張飛)得到的值是一樣的,都是 250,我們豈不是在儲存過程中會遇到麻煩,怎麼安排他們二位的地方呢(總不能讓二位打一架,誰贏了誰呆在那吧),這就需要乙個解決衝突的方法。當遇到這 種情況時我們可以這樣處理,先儲存好了關羽,當張飛進入系統時會發現關羽已經是250了,那咱就加一位,251得了,這不就解決了。我們查詢張飛的時候也 是,一看250不是張飛,那就加個1,就找到了。這時還存在乙個問題。直接用changetohashvalue(趙雲)為251,張飛已經早早佔了他的 地方,那就再加1存到252唄。呵呵,這時我們會發現,當雜湊函式衝突發生的機率很高時,可能會有一群英雄豪傑在250這個值後面扎堆排隊。要命的是查詢 的時候,時間演算法複雜度早已不是o(1)了(所以我們說理想情況下雜湊表的時間演算法複雜度為o(1))。      

這就是說雜湊函式的編寫是雜湊表的乙個關鍵問題,會涉及到乙個儲存值在雜湊表中的統計分布。如果雜湊函式已經定義好了,衝突的解決就成為了改變系統效能的關鍵因素。其實還有很多種方法來解決衝突情況下的儲存和查詢問題,不一定非要線性向後排隊,如果有好的雜湊表衝突的解決方法也能很大程度上提高系統的效 率。

二、

1 基本原理

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

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

總的來說,"

直接定址

"與"解決衝突

"是雜湊表的兩大特點。

2 函式構造

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

a) 除餘法:

選擇乙個適當的正整數 p ,令 h(k ) = k mod p

這裡,p 如果選取的是比較大的素數,效果比較好。而且此法非常容易實現,因此是最常用的方法。

b) 數字選擇法:

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

3 衝突處理

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

4 支援運算

雜湊表支援的運算主要有:初始化(makenull)、雜湊函式值的運算(h(x))、插入元素(insert)、查詢元素(member)。

設插入的元素的關鍵字為 x ,a 為儲存的陣列。

初始化比較容易,例如

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

p=9997; // 表的大小

procedure makenull;

var i:integer;

begin

for i:=0 to p-1 do

a[i]:=empty;

end;

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

function h(x:longint):integer;

begin

h:= x mod p;

end;

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

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;

插入元素

procedure insert(x:longint);

var posi:integer;

begin

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

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

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

end;

查詢元素是否已經在表中

procedure member(x:longint):boolean;

var posi:integer;

begin

posi:=locate(x);

if a[posi]=x then member:=true

else member:=false;

end;

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

三、應用

查詢乙個陣列中重複最多的項 

比如[1,12,4,5,6,7,11,1,1,2,2,2,6]   這裡1和2都重複了3次 

1.先排序,o(n*log(n))  然後在遍歷一次o(n)

輸出的是乙個列表,顯示的是原來列表裡面的每個數出現的次數.

var _array:array=[1,12,4,5,6,7,11,1,1,2,2,2,6];

var _total:array=new array();

for (var i:int=0; i<_array.length; i++) }}

trace(_total);

2.最快的就是使用雜湊表(hash table),複雜度為o(n)-o(1),計算為o(n),讀取為o(1)

var maxid:int = 0;

for (var i:int = 0; i<=n; i++)

trace(a[maxid]);

雜湊表(雜湊表)

雜湊表是最基礎的資料結構之一,利用鍵值對儲存並檢索資料的一種非線性結構。在其它各種結構線性表 樹等資料結構中,記錄在結構中的位置是隨機的,和記錄關鍵字之間不存在確定的關係,因此,在結構中查詢記錄時需進行一系列和關鍵字的 比較 的基礎上。在順序查詢時,比較的結果為 與 兩種可能 在折半查詢 二叉排序樹...

雜湊表(雜湊表)

原文 雜湊表是種資料結構,它可以提供快速的插入操作和查詢操作。第一次接觸雜湊表時,它的優點多得讓人難以置信。不論雜湊表中有多少資料,插入和刪除 有時包括側除 只需要接近常量的時間即0 1 的時間級。實際上,這只需要幾條機器指令。對雜湊表的使用者一一人來說,這是一瞬間的事。雜湊表運算得非常快,在電腦程...

雜湊表(雜湊表)

雜湊技術是在記錄的儲存位置和它的關鍵字之間建立乙個確定的對應關係f,使得每個關鍵字key對應乙個儲存位置f key 這裡我們把這種對應關係f稱為雜湊函式,又稱為雜湊函式。按照這個思想,採用雜湊技術將記錄儲存在一塊連續的儲存空間中,這塊連續儲存空間稱為雜湊表或雜湊表 直接定址法 數字分析法 平方取中法...