数据结构与算法(一)------散列表基本概念

极客时间学习日志,我理解散列表是数组的一种变种,散列表通过映射 将 key 映射为 数组下标。

散列表关联概念

 关键字(key): 原始数据中的 标志信息,
 散列函数(Hash函数):将 关键字 转化为 数组下标的 函数。常见:MD5 、SHA等
 散列值: 散列函数的输出,一般为数组下标。
 散列冲突: 不通的key值 ,通过散列函数,得到同样的散列值
 装载因子:  装载因子 = 散列表中已经被占用的位置数量/散列表总长

散列函数设计原则

 * 数组结果为 非负整数
 * key1 != key2 ,hash(key1) != hash(key2)
 * key1 = key2 , hash(key1) = hash(key2)

解决散列冲突的方法

  1. 开发寻址方法

    • 线性探测法: 通过hansh 映射查看当前位置是否空闲,若被占用,则从头开始找,步长为1,直到找到空闲位置。
    • 二次探测法: 通过hansh 映射查看当前位置是否空闲,若被占用,则从头开始找,步长变为上次的平方,直到找到空闲位置。
    • 双重散列: 设置多个散列函数,hash1、hash2等,若hash1重复,用hash2 依次后推
  2. 链表法
    散列表中的,每个数组下标对应的slot 变更为链表,讲hash 值相同的数据 均放入链表中。

散列表的时间复杂度

查找/删除/插入 最小时间复杂度为 O(1),最差为0(N)

应用

  1. 假设我们有 10 万条 URL 访问日志,如何按照访问次数给 URL 排序?
  2. 有两个字符串数组,每个数组大约有 10 万条字符串,如何快速找出两个数组中相同的字符串?

解决方案

  1. 遍历 10 万条数据,以 URL 为 key,访问次数为 value,存入散列表,同时记录下访问次数的最大值 K,时间复杂度 O(N)。
    如果 K 不是很大,可以使用桶排序,时间复杂度 O(N)。如果 K 非常大(比如大于 10 万),就使用快速排序,复杂度 O(NlogN)。
  2. 以第一个字符串数组构建散列表,key 为字符串,value 为出现次数。再遍历第二个字符串数组,以字符串为 key 在散列表中查找,如果 value 大于零,说明存在相同字符串。时间复杂度 O(N)。
posted @ 2021-03-17 16:40  徐徐前行  阅读(234)  评论(0编辑  收藏  举报