数据结构之散列表

散列表,又称哈希表,是基于数组的扩展,通过散列函数将键值映射为数组下标进行存储。哈希冲突是指不同的键可能映射到相同的数组位置。解决冲突的方法包括开放寻址法(如线性探测、双重散列、二次探测)和链表法。开放寻址法在冲突时寻找空闲位置,而链表法则是在每个数组位置维护一个链表,用于存储冲突的键值对。装载因子是衡量散列表空间利用率的重要指标,理想的散列表应保持较低的冲突率和适当的空位以保证高效操作。
摘要由CSDN通过智能技术生成

数据结构之散列表

什么是散列表

散列表又叫哈希表,利用的是数组支持按照下标随机访问数据的特性,所以散列表其实就是数组的一种扩展。
我们通过散列函数把元素的键值映射为下标,然后将数据存储在数组中对应下标的位置,当我们按照键值查询元素的时候,用同样的散列函数,将键值转换为数组下标,再从对应的数组下标的位置获取数据。

如何构造一个散列函数

那么,要如何构造一个散列函数呢?下面有三点构造散列函数的基本要求。
1、通过散列函数计算得到的散列值必须是一个非负整数。
2、如果key值相同,那么通过散列函数计算得到的值也一样。
3、如果key值不同,那么通过散列函数计算得到的值也不一样。
其实对于第三点的实现是非常困难的,在真实情况下几乎是不可能的,而且,因为数组的存储空间有限,也会加大这种可能性。两个key通过散列函数计算得到相同的值,这种叫散列冲突,又叫哈希冲突。

如何解决哈希冲突

开放寻址法

开放寻址法的核心在于,如果发生了散列冲突,那么我们就重新探寻一个空闲位置,当我们插入一个数据,如果其存储位置已经被占用,我们就从当前位置开始,依次往后查询,直到找到空闲位置。但是查询的话就有点问题了,我们通过散列函数计算key得到的值,获取下标为该值上的数据,如果是就找到了,但是不是的话继续往下找,直到找到一个空闲位置,那么就说明该数不存在。但是这种情况下,如果我们本来删了一个数据,那么这个位置就为空了,这就会导致我们的查询方法失效,本来存在的数据就会被认为不存在,我们可以把被删除的数据做一个标记,如果遇到了有标记的数据,就继续往下找。这个方法叫线性探测法,但是这个方法其实有很大的弊端,因为随着数据量的增多,导致散列冲突的可能性越来越大,空闲位置就越来越少,导致查询的时间越来越长。
这就引出了另外两种经典的开放寻址法,双重散列和二次探测,二次探测的步长是线性探测的二次方。
所谓双重散列,我们可以准备多个散列函数,如果某个冲突了就换下一个。
但是不论采用何种方法,最后冲突的概率就会越来越高。为了尽可能保证散列表的操作效率,我们尽量保证散列表中有一定的空位,我们用装载因子表示空位的多少,装载因子的计算方式是,表中的元素个数/散列表的长度。

链表法

链表法是常用的解决散列冲突的办法,插入的时候我们只需要计算出散列值插入到对应散列值存放的链表中,查找只需要查询到对应链表后,再遍历链表即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值