ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C# 之Dictionary(字典)底层源码解析

2022-05-14 19:34:59  阅读:246  来源: 互联网

标签:Hash 函数 Dictionary C# 地址 算法 源码 key


Dictionary是我们经常使用的,一起来看看它是如何构造的,及有哪些优缺点。

Dictionary是一种键值对的形式存放数据,即 key值 、value 值 一 一映射的。key的类型没有限制,可以是整数、字符串甚至是实例对象。

Dictionary的实现原理,有两个关键的算法,Hash算法 和 解决Hash 碰撞冲突 的算法。key value的映射关系用的就是Hash函数来建立的。

Hash算法

Hash算法是一种数字摘要算法,将不定长度的二进制数据集给映射到一个较短的二进制长度数据集。常见的MD5算法就是一种Hash算法,通过MD5算法 对任何数据生成数字摘要。实现Hash算法的函数 成为Hash函数

对于实例对象和字符串来说,它们没有直接的数字作为Hash标准,因此它们需要通过内存地址计算一个Hash值,计算这个内存对象的函数也就是Hash函数。

Hash函数

Hash函数有很多种算法,最简单的就是 除留余数法【模(Mod)的操作】,取key 被某个不大于散列表 表长m的数p 除后所得余数作为散列地址。即 hash_key =  key % p  , p<=m。

Hash函数有以下特征:

1.相同的key 进行Hash计算,得到的结果一定是同一Hash地址。HashFunc(Key1) == HashFunc(Key1)。

2.不相同的key 进行Hash计算,得到的结果也可能是同一Hash地址。key1 != key2  = >  HashFunc(Key1)== HashFunc(Key2)。【这种现象称之为Hash冲突

Hash冲突

处理Hash冲突的方法中,通常有开放定址法、再Hash法、链地址法、建立一个公共溢出区等。Dictionary使用的是 链地址法 又称 拉链法

 

下图 Hash冲突示意图:

Sandra Dee  和  John Smith 通过hash函数 运算后都落到了02的位置,产生了碰撞和冲突。

 

 拉链法:将产⽣冲突的元素建⽴⼀个单链表,并将头指针地址存储⾄Hash表对应桶的位置。这样定位到Hash桶的位置后可通过遍历单链表的形式来查找元素。

数组内的元素通过next(下一个元素的索引)形成一个单链表。

Hash桶

是解决哈希表而引入的一个概念 ,为每一个hashCode 建立一个桶,桶里面放着一个数组(如上图 数组enteries)。

Dictionary 接口

1.变量定义

 从定义可知,字典的实现底层数据结构依靠的是数组。

Add方法:

      

  

桶数量:
if (buckets == null) Initialize(0); 初始化桶

在初始化Hash桶数量的时候,若未自定义数量,首次分配3个。如果我们自定义了数量,自定义的值  会再根据 primes 数组进行计算,得出到底使用多大的桶数量。

比如 实例化字典 自定义数量 3:

System.Collections.Generic.Dictionary<int, string> dic = new System.Collections.Generic.Dictionary<int, string>(3);

 

Resize();扩容

 Remove方法:

 

 ContainsKey 、TryGetValue 方法,源码贴出,比较简单,不做解析。

 总结:

Dictionary由数组构成,Hash函数作为地址构建,拉链法解决Hash冲突。Dictionary也是线程不安全的,因此在多线程访问的时候,需要自行加lock处理。

 

源码地址:https://referencesource.microsoft.com/#mscorlib/system/collections/generic/dictionary.cs 

参考文献:https://www.cnblogs.com/InCerry/p/10325290.html

标签:Hash,函数,Dictionary,C#,地址,算法,源码,key
来源: https://www.cnblogs.com/zhaolaosan/p/16244067.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有