散列表的概念、构造方法及冲突处理

简单来说查找算法,就是判断现有数据集合中是否有这个元素,或者是否有满足条件的元素。其中的 Hash 算法(散列表)则可以帮助我们判断是否有这个元素,虽然功能简单,但人家性能高啊。通过在记录的存储地址和它的关键码之间建立一个确定的对应关系。这样,不经过比较,一次读取就能得到所查元素的查找方法。相比普通的查找算法来说,仅仅在比较的环节,就会大大减少查找或映射所需要的时间。

判断这个字符串有没有出现过、出现过多少次时可以用哈希。

哈希表(散列表)

采用散列技术将记录存储在一块连续的存储空间中,这块连续的存储空间即称为散列表。下面用一张图给大家展示一下散列表的实现过程:

可以理解为数学函数,Y=F(X),X 为自变量也就是这里的 Key, F( ) 对应图中的 H( ),也就是一个映射关系,Y 因变量也就是对应的值的 存放位置

散列既是一种查找技术,也是一种存储技术。散列只是通过记录的关键码定位该记录,没有完整地表达记录之间的逻辑关系,即通过关键码能推出 Key 值,但是通过关键码对应的值(即位置处的值)不能推出关键码,所以散列存储的关键码和值之间并不对称,因此散列主要是面向查找的存储结构 

散列表的缺陷

散列表并不是适用于所有的需求场景。

  • 散列技术一般不适合在允许多个记录有同样关键码的情况下使用。

因为这种情况下,通常会有冲突存在,将会降低查找效率,体现不出散列表查找效率高的优点。

并且如果一定要在这个情况下使用的话,还需要想办法消除冲突,这将花费大量时间,那么就失去了 O(1) 时间复杂度的优势,所以在存在大量的冲突情况下,我们就要弃用散列表。

  • 散列方法也不适用于范围查找,比如查找最大值或者最小值

因为散列表的值是类似函数的,映射函数一个变量只能对应一个值,不知道其他值,也不能查找最大值、最小值,RMQ(区间最值问题)可以采用 ST 算法、树状数组和线段树解决。

  • 也不可能找到在某一范围内的记录

比如查找小于 N 的数有多少个,是不能实现的,原因也是映射函数一个变量只能对应一个值,不知道其他值。

散列技术的关键问题
在使用散列表的时候,有两个关键的技术问题需要解决:

  1. 散列函数的设计,如何设计一个简单、均匀、存储利用率高的散列函数?
  2. 冲突的处理,如何采取合适的处理冲突方法来解决冲突。

如何设计实现散列函数

在构建散列函数时,我们需要秉持两个原则:

  • 简单

散列函数不应该有很大的计算量,否则会降低查找效率。

  • 均匀:

函数值要尽量均匀散布在地址空间,这样才能保证存储空间的有效利用并减少冲突。

散列函数实现三种方法

1. 直接定址法。

散列函数是关键码(Key)的映射的线性函数,形如:H(key) = a * key + b

如果关键码的集合已知且为 [11,22,33,66,88,44,99]

H(key) = 1/11 * key + 0

 缺点:

  • 我们是看到了这个集合,然后想到他们都是 11 的倍数才想到这 Hash 函数。我们在平常的使用中一般不会提前知道 Key 值集合,所以使用较少。</
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值