散列表

本文详细介绍了散列表的概念,包括散列函数的基本要求、散列冲突的解决方法(开放寻址法、链表法)及其优缺点,并探讨了如何设计散列函数和避免低效扩容。此外,还讨论了散列表在LRU缓存淘汰算法中的应用,以及LinkedHashMap的工作原理。
摘要由CSDN通过智能技术生成

散列思想

散列表采用的是数组支持按照下标随机访问,时间复杂度是O(1)的特性。通过散列函数将元素的键值映射到数组下标,然后将数据存储到对应下标的位置。当查找数据时,通过同样的散列函数计算键值,按照键值查找数据下标对应的值即可。

散列函数

散列函数基本要求:

散列函数计算得到的散列值是一个非负整数
如key1=key2,则hash(key1)==hash(key2)
如key1≠key2,则hash(key1)≠hash(key2)

注意:第三点不是绝对的,可能存在key不同,散列函数相同的情况,这个就是散列冲突。

散列冲突

解决散列冲突的方法:

一、开放寻址法
开放寻址法的核心思想是当出现哈希冲突时,重新探测一个空闲的位置,将其插入。

1.线性探测

插入: 当像散列表中插入数据时,如果某个数据经过散列之后,存储位置已经被占用,就从当前位置开始,依次往后查找,直到发现空闲位置为止。
比如:
在这里插入图片描述
此时要插入一个数据X,经过散列之后X的散列值是4(也就是数组下标为4的位置),发现散列表中下标为4的位置已经被占用,则依次往后查找空闲位置,一直找到下标为7的位置(也就是69的后面)为空,则将X插入到下标为7的位置。

查找: 散列表查找的过程类似于插入,通过散列函数计算散列值,比较数组下标为散列值的位置的值是否等于要查找的值,一直遍历到空闲位置,说明不存在。

删除: 删除操作稍微复杂点,若查找到值,直接删除,会存在问题,比如说删除下标为7的值,位置就变成空闲了,此时要是进行查找(找到空闲位置查找就停止,说明不存在),就会影响下标为7以后的位置是否存在的判断。如何解决呢?我们可以不删除,将要删除的位置标记为deleted,在查找的时候遇到deleted的继续查找即可。

存在问题: 插入的数据越来越多时,空闲位置越来越少,线性探测时间越来越长,发生冲突的概率越来越大。

应用: ThreadLocal里面的ThreadLocalMap

2.二次探测

二次探测的方式和线性探测类似,线性探测每次的步长是1,二次探测的步长可以使原来的二次方或者不等于1的固定步长。

3.双重散列

使用一组散列函数,第一个散列函数计算的散列值冲突,就用第二个散列函数计算,一直到不冲突为止。

二、链表法

在散列表中,每个桶或者槽

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值