用雜湊表搜尋物件

2021-08-22 01:40:43 字數 2346 閱讀 1623

.net framework中的大多數容器都是序列式容器(sequence containers):它們按順序儲存物件。這種型別的容器功能很多——你可以以任何特殊的順序來儲存任意數量的物件。

然而,這種多功能性是以一定的效能為代價的。在乙個序列中查詢乙個特殊的物件所需要的時間取決於容器中物件的數量。如果我們沒有對容器中元素進行排序,那麼隨著元素數量的增加,你所需要的查詢時間也就直線增加了:如果容器中元素的數量增加了一倍,那麼你用來查詢乙個特殊元素的時間也就增加了一倍。然而,如果我們對容器中的元素進行了排序,那麼查詢時間就是隨著元素數量的對數而增加的了:要使查詢乙個元素的時間增加一倍,你必須使集合中的元素數量增加四倍。如果你用乙個key來搜尋物件,你可以用比序列式容器更好的方法來儲存你的物件。你可以用雜湊表(hash table)。

雜湊表根據乙個叫做hash的數字關鍵字(key)將物件儲存在buckets中。hash value是從物件中的值計算得來的乙個數字。每個不同的hash value都會建立乙個新的bucket。要查詢乙個物件,你只需要計算這個物件的hash value並搜尋相應的bucket就行了。通過快速地找到相應的bucket,就可以減少你需要搜尋的物件數量了。

例如,設想在乙個資料結構中有一些客戶記錄,你想通過信用卡號來搜尋那些記錄。乙個簡單的雜湊函式將運用信用卡號的後兩位數字,這會形成100個buckets——從00到99的每個兩位數的數字都會建立乙個bucket。(同樣,運用後三位數字會建立1000個buckets。)只需要查詢乙個bucket,你就可以找到任何記錄了,而不需要查詢所有的buckets。

然而,同任何事情一樣,並不是一切都這麼簡單的。如果你用信用卡號建立了乙個雜湊函式,而你想通過姓名來查詢客戶,你就需要查詢整個雜湊表,這樣會花很多時間。這是因為雜湊表是用乙個不同的字段作為key的。而且,如果你查詢整個雜湊表,那麼元素就沒有必要按你期望的順序來排列了。元素是根據hash value來排列的,而不是根據keys排列的。

在本篇文章中,我將詳述我在前面的文章(「為更好的集合建立類」)中的樣例,讓你修改一條員工記錄。假設有乙個很大的公司,公司裡有上千位員工,你想用最快的方法來找到一條記錄。所有員工的乙個雜湊表可以使搜尋在最短的時間完成。

乙個雜湊函式需要有一定的屬性。對於初學者來說,雜湊函式必須是不變的。這就是說相同的key必須生成相同的hash value,一旦建立了物件,hash value就不能改變了。如果hash value改變了,你在雜湊表中就再也找不到相應的物件了。

雜湊函式需要的第二個屬性就是能夠平均分配buckets。如果所有的物件都生成相同的hash value,那麼就需要更多的時間來查詢乙個特殊的物件。

實際上,這兩個原則是很容易遵循的。在.net framework中有178個類過載了gethashcode(),從而更好地發揮它們的作用。所有的.net fcl(framework class library)中類的實現都確保了hash value的更好的分配,並遵循了唯一性的原則。你應該確定你自己的類和結構是否需要過載gethashcode()方法。最簡單的(通常也是最好的)方法就是在key中選取乙個不變的成員,並運用那個成員所生成的hash value。

要把員工新增到乙個雜湊表中,你可以建立乙個九位數的號碼並把它作為key:

int hash = 111223333;

for (int i = 0; i < 100; i++)

社會保險號滿足了乙個好的hash key的要求:它不會改變,它可以合理地分配、value取決於號碼而不是reference。(你需要運用基於value的hash key而不是基於reference的hash key以避免我以前提到過的問題。)

運用這個hash key來查詢物件也很簡單:

int ssn = int32.parse(this.ssn.text);

currentemp = (employee)members[ssn];

if (currentemp != null)

else

lastname.text = "not found";

在c#中,你可以用陣列語法在雜湊表中查詢物件。該語法強調了恆定時間搜尋的概念:你可以把陣列訪問看做是乙個快速的操作,而不是乙個代價很高的函式呼叫。

關於雜湊表最後的乙個重點是,同所有的集合一樣,它們也儲存引用(references)。你不需要任何額外的工作來更新雜湊表中的物件。一旦你引用了雜湊表中的乙個物件,你可以隨意修改它。記住,同樣的原則不適用於keys。你可以編寫**來改變keys,但如果那個**修改了hash value,你就會丟失你的集合中的物件。

雜湊表是很有用的、有效的容器。但是,要有效地運用它們,你需要了解容器和容器中物件的狀態之間的關係。當你可以用從物件計算得來的不變的value來搜尋物件時,雜湊表就很有用。如果你用不同的順序(通過姓名、社會保險號、或年齡)在物件中搜尋,那麼雜湊表就不那麼有用了。

雜湊表 雜湊表

一 定義 雜湊表 hash table,也叫雜湊表 是根據關鍵碼值 key value 而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做雜湊表。雜湊表的做法其實很簡單,就是把key通過乙個固定的演算法函式...

雜湊表(雜湊表)

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

雜湊表(雜湊表)

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