簡體   English   中英

哈希過程如何在Dictionary中工作<TKey, TValue>

[英]How does the process of hashing work in Dictionary<TKey, TValue>

字典中的哈希處理如何工作? 我讀到使用字典可以更快地查找。 但是不明白怎么辦? 哈希和映射到索引如何發生? 找不到任何好的參考。

編輯:如何從哈希函數的結果中獲取存儲對象的實際內存位置?

哈希表或字典是一種存儲鍵-值對的數據結構。 哈希表的優點在於,給定鍵找到對應的值非常快。 簡化后,在哈希表中查找鍵值對的時間並不取決於表的大小。 將其與將鍵值對存儲在列表或數組中進行比較。 要查找鍵值對,您必須從頭開始搜索列表,直到找到匹配的鍵。 列表越長,找到鍵值對所需的時間就越多。 使用big-O表示法可以說,在哈希表中查找鍵的順序為O(1),而通過線性搜索在列表中查找鍵的順序為O(N)(簡化)。

要將鍵值對插入哈希表中,您首先必須計算鍵的哈希碼。 在.NET中,所有對象都有一個名為GetHashCode的方法,該方法返回該特定對象的哈希碼(32位整數)。 相等的對象返回相同的哈希碼很重要,但是如果不同的對象返回不同的哈希碼,這也非常有用。 注意不要誤認為不同的對象不能返回相同的哈希碼-它們可以,但是會導致沖突 (請參閱下文)。

例如,考慮兩個字符串的哈希碼:

"Boo" 0x598FD95A
"Foo" 0x598FD8DE

即使字符串非常相似,它們也具有不同的哈希碼。

我在這里簡化一些事情,以關注哈希表的重要方面,因此,現在讓我們說,Internally Dictionary<TKey, TValue>將鍵值對存儲在數組中。 要在將鍵值對存儲在此數組中的索引中找到索引,您必須以數組大小為模來計算鍵的哈希碼。 假設數組的大小為5:

Index("Boo") = 0x598FD95A % 5 = 4
Index("Foo") = 0x598FD8DE % 5 = 0

這導致此內部哈希表數組:

+---+---------+
| 0 | "Foo"   |
+---+---------+
| 1 | (empty) |
+---+---------+
| 2 | (empty) |
+---+---------+
| 3 | (empty) |
+---+---------+
| 4 | "Boo"   |
+---+---------+

在哈希表中查找條目非常快。 您只需要以內部數組的大小為模來計算鍵的哈希碼,然后在該索引處檢索字符串。

現在考慮鍵“ Zoo”:

Index("Zoo") = 0x598FDC62 % 5 = 0

它具有與鍵“ Foo”相同的索引。 這導致所謂的碰撞 哈希表的正確實現將必須處理沖突,並且這樣做不同的策略 同樣,隨着內部數組的填充,數組中的空白元素將越來越少,從而導致沖突數量增加。 負載系數是內部陣列中已用元素與總元素之間的比率。 在上面的示例中,負載系數為2/5 = 0.4。 當負載因子超過特定閾值時,大多數哈希表實現都會增加內部數組的大小。

如果您想更多地了解其中一些概念,則必須研究與其他答案相關聯的一些更全面的資源。

詞典中的哈希處理使用一種稱為鏈接的技術。 通過鏈接,輔助數據結構可用於保留任何沖突。 具體來說,字典中的每個廣告位都有一個映射到存儲桶的元素數組。 在發生碰撞的情況下,碰撞元素位於鏟斗列表的前面。

有關更多詳細信息,請參見MSDN上的這篇文章。

通過使用稱為哈希圖的計算機科學概念。 這確實比搜索列表更快。 通過使搜索不再需要遍歷列表直到找到匹配項,該方法可以起作用。 相反,鍵是“ 散列的 ”,並用作列表的索引。 該散列函數幾乎總是比搜索列表更快(使用多個比較進行迭代)。

通常,通過獲取哈希值%數組大小,可能會產生沖突。

正如我試圖在回答其他問題時所解釋的那樣,字典使用哈希鍵進行查找。 因此,如果您有一個自定義對象類型作為鍵,那么一切都取決於自定義對象的GetHashCode()實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM