1.介绍一下散列表
散列表是一种数据结构,用键值对来储存数据,通过哈希表的映射快速找到元素,从而实现常数级别的数据插入,删除,查找操作。如果使用直接使用数组的话则需要通过遍历来获取元素,时间复杂度为O(n)。
2.为什么使用散列表
快速查找和删除
简单实现:散列表结构相对简单
3.拉链寻址和开放寻址的区别
拉链寻址和开放寻址都是用来解决哈希冲突的方案,区别在于:
拉链寻址在冲突的索引位置上形成链表,将冲突的元素存在其中来解决冲突,缺点是链表可能会边长,增加查找的时间复杂度。
开放寻址通过在哈希表内寻找其他空位置来解决,缺点是删除操作会变得复杂,因为删除一个元素后会导致重新排列
4.还有其他什么方式可以解决散列哈希索引冲突
合并散列:合并散列是开放寻址和单独链接的混合,冲突元素在哈希表中进行连接,不需要再去循环遍历寻找碰撞元素也就是a和b发送碰撞的时候,a可以快速的查找到b。
杜鹃散列:和杜鹃鸟在孵化时,雏鸟会将其他蛋或幼崽推出巢穴很像,杜鹃散列会使用两个哈希表,当发生冲突时,将冲突元素推到另一个哈希表中。
跳房子散列:是一种基于开放寻址的算法,它借鉴了杜鹃散列发生冲突时挪走元素的特点,通过重排来解决冲突,兼具线性探测和链接地址的特点。
罗宾汉哈希:罗宾汉哈希是一种基于开放寻址的冲突解决算法,通过冲突元素与理想位置的偏移值来决定,对偏移值小的进行劫富济贫,把它的位置让给偏移值大的。也就是冲突是通过偏向从其“原始位置”(即项目被散列到的存储桶)最远或最长探测序列长度(PSL)的元素的位移来解决的。
5.对应的Java源码中,对于哈希索引冲突提供了什么样的解决方案
在Java中,java.util.HashMap
是最常用的哈希表实现之一,具体使用了拉链法和红黑树来解决哈希冲突
HashMap用链表来储存冲突的元素,当发生哈希冲突时,新元素添加到链表的尾端
当某个桶中的链表长度超过一定阈值(默认是8)时,HashMap
将链表转换为红黑树。这种转换能够提高查找效率,使得最坏情况下的查找时间复杂度从 O(n) 降到 O(log n)。因为这样的树状结构是2的n次幂结构。