散列表(Hash Table)

散列表(Hash Table


1.散列表

散列表(Hash Table)又名哈希表/Hash表,是根据键(Key)直接访问在内存存储位置值(Value)的数据结构,它是由数组演化而来的,利用了数组支持按照下标进行随机访问数据的特性.

例子1:

假设有100个人参加马拉松,编号是1-100,如果要编程实现根据选手的编号迅速找到选手信息?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ytlZtM6w-1692966003631)(C:/Users/czh/AppData/Roaming/Typora/typora-user-images/image-20230825175424045.png)]

实现思路:

让选手的编号存储到数组中,其中选手的编号就是数组的下标,我们需要查询某一个选手的时候,只需要根据选手编号作为数组下标查询即可,时间复杂度O(1),效率很高

什么是时间复杂度O(1)?

是衡量算法效率的指标之一,O(1)表示无论输入规模的大小如何,算法的运行时间都是常数级别的,即算法的执行时间不随输入的增加而增加。这意味着算法的执行时间是固定的,不受输入规模的影响

例子2:

假设有100个人参加马拉松,不采用1-100的自然数对选手进行编号,编号有一定的规则比如:2022ZHBJ001,其中2022代表年份,ZH代表中国,BJ代表北京,001代表原来的编号,那此时的编号2022ZHBJ001不能直接作为数组的下标,此时应该如何实现?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d87UBQo8-1692966003632)(C:/Users/czh/AppData/Roaming/Typora/typora-user-images/image-20230825175544891.png)]

实现思路:

让选手的编号(2022ZHBJ001)进行hash计算,hash计算后得到一个整数值,可以做为数组的下标进行存储。

总结:

散列表用的就是数组支持按照下标访问数据时时间复杂度为O(1)的特性来实现的高效访问,当存储数据时,通过散列函数得到数组的下标然后将数据放入到该位置中去,然后进行读取。可以看出,散列表的实质是数组,是一种升级版的数组。


2.散列函数hash(key)

含义:将键(key)映射为数组下标的函数叫做散列函数

散列函数的基本要求:

  1. 散列值是一个非负整数
  2. 如果key1 = key2 ,那么hash(key1) == hash(key2)
  3. 如果key1 != key2,那么hash(key1) != hash(key2)

上面要求的前2条很容易理解,也很容易实现,但是第三条是不太容易实现的,当两个key的值不同的时候,他们的hash值不敢保证一定不一样,想找一个散列函数能够做到对于不同的key,计算得到的散列值都不同几乎是不可能的,因而会产生散列冲突


3.散列冲突(哈希冲突/哈希碰撞)

根据一定的规则放进存放哈希值的数组中,然后下标为1的数组已经有值了,后面根据规则,判定某个数也需要放到下标为1的数组中,这样就导致了只有一个位置两个人都要坐,就引起了冲突。(不同的key值产生的H(key)是一样的)。这就是散列冲突(或者哈希冲突,哈希碰撞,就是指多个key映射到同一个数组下标位置)

例子:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Flc81KZR-1692966003632)(C:/Users/czh/AppData/Roaming/Typora/typora-user-images/image-20230825180438843.png)]

上图中的选手编号,如果进行hash计算后得到的值是一样的,则会计算到数组中的同一个下标中.


hash冲突解决方案

------链表法

原理: 通过散列函数得到的目标位置如果已经有数据的话,就形成一个链表,将冲突的数据放入链表中去,这样插入的时间复杂度依旧是O(1),但是有弊端,就是当链表长度过长的时候,查询数据的速率会变慢,所以在有些时候,链表会转化为树来减少查找的时间。如图所示,hashmap用链表来解决hash冲突

在这里插入图片描述

解读:
1.散列表对应数组的每一个下标位置,称为:slot槽
2.每一个slot槽位,对应一条链表,用于解决散列冲突
3.当不同的元素key,通过散列函数计算出了相同的散列值,存在散列冲突
4.槽位发生散列冲突,只需在槽位的链表上增加一个节点即可

更多解决方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值