散列表/哈希表
特点:
- 通过建立键 key 与值 value 之间的映射,实现O(1)时间复杂度的高效的元素查询
举例:
- 树
- 图
图解:
常用操作:
- 初始化
- 查询操作
- 添加键值对
- 删除键值对
哈希函数(hash function):
- 作用:作用是将一个较大的输入空间映射到一个较小的输出空间
- 索引位置(桶)计算:
index = hash(key) % capacity
哈希冲突
- 因为输入空间远大于输出空间,所以理论上一定存在冲突
- 解决方式:
- 链式地址
- 原理:将所有发生冲突的键值对存储在同一个桶的同一链表中(redis hash、go map)
- 当链表很长时,可以将链表转换为’AVL 树’或’红黑树’,以提高查询效率
- 开放寻址
- 原理:不引入额外的数据结构,而是通过“多次探测”来处理哈希冲突
- 具体方法:
线性探测
:- 采用
固定步长
的线性搜索:- 插入时,若发现桶内已有元素,则从冲突位置向后线性遍历(步长通常为1),直至找到空桶,将元素插入其中
- 查询时,若发现哈希冲突,则使用相同步长向后进行线性遍历,直到找到对应元素。如果遇到空桶,说明目标不在哈希表中
- 采用
平方探测
:- 采用
探测次数的平方
步长的搜索:- 与线性探测类似
- 采用
多次哈希
:- 使用多个哈希函数
- 插入时,若出现冲突,则尝试更换哈希函数,直到找到空位
- 查询时,若出现冲突,则尝试更换哈希函数,直到找到元素或者出现空位
- 使用多个哈希函数
- 再哈希
- 原理:新建一个更大的哈希表,使用新的哈希函数将原先键值对重新映射到新的地址
- 链式地址