liyizhu

散列

定义

  • 将关键字映射到存储位置的过程称为散列。
  • 散列是一种用以实现信息存储和快速检索的技术。
  • 常用于执行优化搜索和符号表的实现。

效率

  • 平均时间复杂度:O(1)
  • 最坏时间复杂度:O(n)

散列的组成成分

  • 散列表
  • 散列函数
  • 冲突
  • 冲突解决技术

散列表

  • 在数组中,关键字为k的元素将存储到数组的位置k。
  • 给定关键字k,仅通过查看数组的第k个位置就可以找到该元素,这称为直接寻址。
  • 当关键字的实际存储数目相对于关键字的取值范围较小时,可以使用散列表。

散列函数

散列函数用于将关键字转换成索引。
一个好的散列函数应具有一下特点:

  • 最大限度减少冲突
  • 简单并快速计算
  • 将键值在散列表中均匀分布
  • 能使用关键字提供的所有信息
  • 对一组给定的关键字具有一个高负载因子

负载因子

负载因子 = 散列表中元素的个数 ÷ 散列表的长度

冲突

冲突是指两个记录通过散列函数映射到相同的地址空间。

冲突解决技术

寻找替代位置的过程称为冲突解决。

  • 直接连接法:链表数组的应用
    •   分离链接法
  • 开放定址法:基于数组实现
    •   线性探测法(线性搜索)
    •   二次探测法(非线性搜索)
    •   双重散列法(使用两个散列函数)

分离链接法

当两个或多个记录散列到相同的位置时,将这些记录构成一个单向链表

开放定址法

线性探测法
rehash(key) = (n + k) % tablesize (k为步长)

  • 线性探测中,从发生冲突的原始位置开始按顺序搜索散列表,直到查找到未被占据的位置。
  • 聚集是线性探测存在的一个问题,即散列表中包含一组连续的被占据的位置。
  • 探测的下一个位置由步长确定,步长应该与散列表的长度互斥,较大的步长并不能避开聚集问题。

二次探测法
rehash(key) = (n + k²) % tablesize (k为1、2、3......)

  • 二次探测中,从发生冲突的出事位置i开始,一次探测i+1²、i+2²、i+3²等。
  • 尽管二次探测可以减少聚集,但还是存在聚集的可能

双重散列法

  • 探测间隔由另一个散列函数计算生成,双重散列法更好地减少了聚集
  • 第二个散列函数应遵循:h2(key) ≠ 0 且 h2 ≠ h1
  • 双重散列中,依次探测h1(key)、 [h1(key)+h2(key)] mod tablesize、[h1(key)+2×h(key)] mod tablesize、[h1(key)+3×h(key)] mod tablesize、[h1(key)+4×h(key)] mod tablesize等。
  • 使用少量探测序列,但需要花更多的时间

散列表实现及相关问题

https://github.com/liyizhu/structs-and-algorithm/tree/master/hash

 

posted on 2019-04-09 00:43  liyizhu  阅读(428)  评论(0编辑  收藏  举报

导航