散列表

1. 散列思想

  • 散列表(Hash Table),(散列-哈希-Hash)
  • 特性:下标随机访问(时间复杂度O(1)),数组扩展
  • 词汇:键(key)、关键字、散列函数、散列值(下标)

2. 散列函数要求

  1. 散列函数计算得到的散列值是一个非负整数
  2. 如果 key1 = key2,那 hash(key1) = hash(key2)
  3. 如果 key1 ≠ key2,那 hash(key1) ≠ hash(key2)。
  • 问题:很难找到一个不同的key对应的散列值都不一样的散列函数(要求3),即散列冲突(数据无限,空间有限)

3. 散列冲突

  • 开放寻址法
    • 核心思想: 如果冲突,则重新探测新位置
    • 方法
      • 线性探测法
      • 二次探测
      • 双重散列
  • 线性探测法
    • 插入:先求散列值,冲突时,往后查找,直到找到空闲位置插入
    • 查找:类似插入,至空闲位置还未找到则不存在。
    • 删除:类似插入,标记删除元素,查找时跳过它(影响查找)
    • 问题:数据多时,算法退化 -> O(n)
  • 二次探测:hash(key)+n2
  • 双重散列:一组散列函数
  • 装载因子:散列表的装载因子 = 填入表中的元素个数 / 散列表的长度
  • 链表法
    1. n个数据,m个槽
    2. 槽对应链表,存储散列值相等的元素
    3. 按槽插入,时间复杂度O(1)
    4. 查找、删除,槽内链表查找节点,平均时间复杂度O(n/m)

4. 散列表和链表联合使用

  • 散列表:增删查快,但是无序
  • 链表(或跳表):排序
4.0 缓存淘汰策略
  • 先进先出策略 FIFO(First In,First Out)
  • 最少使用策略 LFU(Least Frequently Used)
  • 最近最少使用策略 LRU(Least Recently Used)
4.1 LRU 缓存淘汰算法
  • 主要操作:添加,删除,查找
  • 时间复杂度:均为O(1)
  • 散列表 + 双向链表
    1. 散列表:用于查找,复杂度O(1)
    2. 散列表使用拉链(单链表)解决散列冲突(链表法)
    3. 双向链表:保存数据的顺序关系,便于删除、新增,复杂度O(1)。单链表时间复杂度o(n)
  • 添加分析
    1. 是否存在
    2. 如果存在,移到尾部
    3. 如果不存在,且双向链表是否已满,删除头部节点,尾部添加
    4. 如果不存在,且未满,尾部添加
4.2 Redis 有序集合
  • 有序集合的两个重要属性:键值(key),分值(score)
  • score操作:跳表实现的有序集合,区间查找效率高
  • key操作:散列表,根据key快速查找,时间复杂度O(1)
  • 类似LRU的解决方法:跳表 + 散列表
4.3 Java LinkedHashMap
  • 支持 LRU 缓存淘汰策略
  • 支持按照访问时间排序
  • 双向链表 + 散列表
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值