C# Dictionary 冲突处理策略解析
C# Dictionary 冲突处理策略解析
开散列策略
Dictionary与HashTable的冲突处理策略不同,后者采用的是二度哈希Rehashing,而前者采用的是开散列方法(open hashing),也称链接技术(Chaining)。
注意,开散列、链接技术是一类冲突解决策略,其基本思路为把哈希值相同的元素归于同一个集合中,把该集合处理为一个链表,链表的头节点存储于哈希表中。
数组内的“链接”
而Dictionary对开散列策略的实现略有不同,没有把集合处理为一个链表。
Dictionary使用数组entries存放数据,entries数组中存放的是Entry结构:
struct Entry
{
public int hashCode; //31位散列值,32最高位表示符号位,-1表示未使用
public int next; //下一项的索引值,-1表示结尾
public TKey key; //键
public TValue value; //值
}
通过next作为索引,在数组entries中构成了“链式结构”。这种链接方式,和将集合处理为链表相比,数据存放在了一片连续的内存区域。
将哈希函数与数据数组解耦
同时,Dictionary的冲突处理策略通过一个数据桶buckets将哈希函数与数据数组进行了解耦。
即根据key得到的哈希值是buckets的索引,而不是数据数组entries的索引。通过buckets的索引得到第一个哈希值相等的数据。
这样的解耦带来的好处是,当哈希函数变化时,entries不需要变化。(虽然还不知道什么时候需要对Dictionary的哈希函数进行改变)。
参考
- C# Dictionary源码剖析 :https://blog.****.net/exiaojiu/article/details/51252515
- 《Unity 3D脚本编程 使用C#语言开发跨平台游戏_PDF》第四章 4.6