持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情
哈希表基础
我们用一个力扣题来引入hash表
我们的思路是利用映射的关系,得到每一个元素的出现次数,然后找出所要的结果。
其中题中还有一个要求是 假定该字符串只包含小写字母
那我们是不是可以用一个数组存储上可能出现的值,例如让 0索引对应a,1索引对应b......
这道题也是很简单的,看一下就会了。
而这道题就是有哈希表的思想 我们设置的 26长的数组就是一个哈希表;将字符转换为索引的过程就是哈希函数。
我们想做的是每一个字符和一个数字间进行一个映射的关系。这道题中,我们将每一个字符都和一个索引相对应,
哈希表充分体现了算法领域的经典思想:空间换时间
哈希表是时间和空间之间的平衡
哈希函数的设计是很重要的
哈希冲突的解决
哈希函数的设计
原则
- 一致性:如果
a==b,则hash(a) == hash(b) - 高效性:计算高效简便
- 均匀性:哈希值分布均匀
哈希冲突的处理方法
链地址法
在对数据经行存储的时候,经过哈希函数的结果有时可能不是第一次出现。
那么我们就可以对其进行
链表的连接,对重复的数据进行链式存储。
其实这个链式存储实际上就时保存一个 查找表。这个查找表可以是链表,数组,或者树等等。
-
根据元素的哈希值计算出索引后,根据索引来哈希表中的数组里存储数据,
-
如果索引相同的话,那么就以链表的方式将新元素挂到数组对应的位置中,
-
这样就很好的解决了哈希冲突的问题了,因为每一个位置都对应了一个链,
-
它的本质就是一个查找表,查找表的本质不一定是使用链表,
-
它的底层其实还可以使用树结构如平衡树结构,
-
对于哈希表的数组中每一个位置存的不是一个链表而是一个 Map,
-
通过哈希值计算出索引后,根据索引找到数组中对应的位置之后,
-
就可以把你要存储的元素插入该位置的 红黑树 里即可,
-
那么这个 Map 本质就是一个 红黑树 Map 数组,这是映射的形式,
开放地址法
开放地址法的主要工作方式是寻找空白的单元格来放置冲突的数据项。
当遇到哈希冲突的时候,可以不向上面一样进行链表的存储,反而将数据放到顺延下去的其他位置就可以
根据探测空白单元格位置方式的不同,可分为三种方法:
- 线性探测
- 二次探测
- 再哈希法