Dictionary<TKey,TValue>

/*
* 先将 key 和 bucket 的长度一起,经过简单的 hash 算法计算出元素应该放在哪个 bucket .
* 但是,元素并不是放在 bucket 里面的,bucket 只是对元素存放位置的第一次计算, 它其实是为了解决 hash 冲突设计的,它并不存放我们添加的元素.
* 当确定了 bucket 后,再将元素存放在 Entry[] 中, 这个数组才是实际存放元素的容器.并且所有元素都存放在这个数组中.
* 因此,当 Dictionary 需要扩容的时候,不仅 bucket 需要扩容, Entry[] 也需要扩容,当然,数组长度是不能变的,肯定是新建一个容量更大的,然后 copy 一份老的数据过去.
* 前面说了,hash 会冲突,比如 1%3=1 , 4%3=1 ,那么这时候,1 和 4 这两个数作为 key ,就会导致 hash 冲突,它们两个通过计算后,都会选择 bucket[1] 这个"桶",
* 那么,问题来了,
* bucket[1] = ? , 如果没有 hash 冲突,这个值完全可以用来存储 key 对应的 value.但是现在有两个"相同的" key 对应的 value 都需要存到这里,怎么办呢?
* 答案是"栈"+"链表",之所以加个引号,是因为不是真正用的栈和链表,而是借用了它们的思想.
* bucket 里面存储的是当前 bucket "里面" 最后添加的那个元素在 Entry[] 中的下标.
* 比如,我们先添加一个 dic.Add(1,value) ,那么,这时候,Entry[] 就有1个元素了,Entry[0]
* 我们假设通过 hash 计算,这个键值对元素应该放在 bucket[1] 这个桶里面,因此这时候 bucket[0] = 0 ,等号右边的 0 表示 Entry[] 的下标.
* 我们再 Add(4,value),这时候,Entry[] 有2个元素,Entry[0] 和 Entry[1],
* 并且我们假设通过 hash 计算,这个键值对元素也应该放在 bucket[1] 这个桶里面,
* 那么,这时候 bucket[0] 就不在 = 0了,而是 = 1,
* 并且 Entry[1] 中的元素(Entry 类型)有个 next 字段,其值 = 0, 这个 0 就是 Entry[] 的索引,表示该元素的下个元素是 Entry[0] ,进一步说就是
* 桶1里面有两个元素,最上面的(第2次放进去的)是 Entry[1] ,第2个(第1次放进去的那个)是 Entry[0],并且通过 Entry[1] 是可以找到 Entry[0] 的.
* 到这里,突然发现 bucket 这个命名很形象.
* 桶有什么特点呢?桶就好比是一个栈,"先进后出",最先进去的在最下面.
* 也就是说,一个桶第一次装进去的那个元素的 next 永远 = -1
* 第2次进去的指向第1个,第3次进去的指向第2个......
* 感觉这个设计好巧妙!!!
*
*/

转载于:https://www.cnblogs.com/refuge/p/10433625.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值