程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#中用哈希表搜索對象(1)

C#中用哈希表搜索對象(1)

編輯:關於C語言
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。

員工數據庫的一個明顯的hash key就是社會保險號(Social Security Number)。它不僅不會改變, 而且九位數的這個號碼也可以讓你任意運用以得到你期望的性能。你可以下載樣例,看看運用hash keys 進行搜索和運用序列式容器進行搜索有什麼不同。

要把員工添加到一個哈希表中,你可以創建一個九位數的號碼並把它作為key:

int hash = 111223333;
for (int i = 0; i < 100; i++)
{
   string lastname = "Person" + i.ToString();
   e = new Employee ("Employee", lastname, (200-i)*200);
   members.Add(hash++, e);
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved