【程序员必备小知识-基础7】浅谈哈希表

373 阅读2分钟

引言

前面聊了一些底层的数据结构,然后我们来扩展一下,数组的存储和读写我们都熟悉了,我们所需要的数据是需要索引才能获取到,但是在实际的开发中,你所拥有的索引并不一定是数字,你得想办法转化成数字,那显然数组是不能满足要求的,于是我们引入了哈希表。

哈希表

假设我们有一个场景:就是用一个字符串key取对应的商品信息也就是Value,直接用数组取肯定是取不到的,于是我们就引入了哈希表,哈希表也是一种数据结构,底层其实是一个数组,但是此时我们的索引下标是通过Key计算得到的,我们先通过key拿到HasCode,返回值是一个int,然后再用HashCode对数组取长度取余数,拿到余数就拿到对应商品的索引值了。拿到索引值对数据的读写就很方便了。

Hash冲突

这里有个疑问:如果使用哈希表在计算出的数组索引中已经有一个值了,那我们还要不要插入呢?如果插入就会覆盖原来的值,不插入这个值就会丢了,就让我们犯了难,怎么办呢?还记得前面提到的链表嘛?这个会很轻松的让我们解决这个问题,因为这个问题的本质就是数据插入问题,解决数据插入最直接的办法就是使用链表。

Hash表的改造

我们可以应用数组加链表的形式对Hash表进行改造,数组不存储数据,keyvalue,数组只做KeyValue的指针,真正存储数据的是链表,这样我们解决了数据的存储问题,一旦发生Hash冲突,只需要把相同下标不同Key的元素存储起来就可以了,取的时候直接遍历链表找到对应的Key就行了。

极端条件下,Hash表会退变成链表,那我们查询数据的时间复杂度就又上来了,所以为了减少hash冲突,我们也要分情况扩容,同时在HashCode的计算中使01分布均匀,减少Hash碰撞的产生。