数据结构 ——哈希表

     此篇文章只是记录一下学习hash表的知识点,并不涉及代码。

概念:哈希存储是一种由关键字本身决定其储存位置的存储结构

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。(百度百科)

把关键字K代入某个函数H(K),得到的函数值作为K的存储位置,即:
K的存储地址 = H(K)

H(K)称为哈希函数,这种存储结构成为哈希表。

在查找时,理想情况下时间复杂度为 O(1)

哈希函数的特点:

Hash(输入) = 输出

输入:可为不固定长度的值。
输出:固定长度的值。
单向不可逆: 无法从输出值反推到输入值。
输出值能反映输入值大部分特称,即使输入值只有微笑的变化,输出值也会完全不同。

例题:

关键字k的序列为{20,30,70,12,18}
哈希函数为:h(k)=k % 7,则构造的哈希表为:
地址: 20%7 =6; 30%7=2; 70%7=10; 12%7=5; 18%7=4

在这里插入图片描述
如果在上面添加一个关键字37;
它的地址: 37%7=5…2。关键字37和上面的关键字30相同。这时候就产生冲突。

冲突

关键字不同,哈希函数值相同。冲突的关键字成为同义词。

冲突是无法避免,构造好的哈希函数的方法,可减少冲突,应有较好的随机性。

哈希函数方法有:

1.直接定址法
2.除留余数法
3.平方取中法
4.折叠法
5数值分析法

1.直接定址法

直接定址法是一关键字k本身或者关键字加上某个数值常量c作为哈希地址的方法。

H(k) = k+c

这种哈希函数计算简单,并且不可能有冲突发生,当关键字分布基本连续时,可直接用直接定址法的哈希函数。若关键字不连续将造成内存单元大量浪费。

2.除留余数法

取关键字K除以哈希表长度m所得的余数作为哈希函数地址的方法。
即:

H(K) = k%m

这是一种简单常见的构造方法。这种方法的关键是选择好哈希表的长度m。使得数据集合中的每一个关键字通过该函数转化后映射到哈希表的任意地址上的概率相等。研究表明,在m取值为素数(质数)时,冲突的可能性较少。

3.平方取中法。

取关键字平方后的中间几位作为哈希函数的地址(若超出范围时,可再取模)。

  1. 折叠法

这种方法适合在关键字的位数比较多,而地址区间较少的情况下。

将关键字分割成位数相同的几部分。然后将这几部分的叠加和作为哈希地址。(若超出范围时,可再取模)。

5.数值分析法

若事先知道所有可能的关键字取值的时候,可通过对这些关键字进行分析,发现其变化规律,构造出相应的函数。

冲突的解决方法

常用的处理冲突的方法有开放定址法链地址法两大类。

1.开放定址法

用开放定址法处理冲突就是当冲突发生时,形成一个地址序列。沿着这个序列逐个探测,直到找出一个"空"的开放地址。将发生冲突的关键字值存放到该地址去。

Hi=(H(k)+d(i)) % m ,i = 1,2,…k (k <m-1)

其中H(k)为哈希函数,m为哈希表长,d为增量函数,d(i) = d1,d2…dn。

1).线性探测法

线性探测法是从发生冲突的地址(设为d)开始,依次探查d+1,d+2,…m-1(当打包表尾m-1时,又从0开始探查),直至到找到一个空闲的位置来存放冲突处的关键字。

d0 = H(k)
di = (di-1+1) % m (1 ≤ i ≤ m-1)

利用线性探查法处理冲突容易造成关键字的 “

堆积”

问题。这是因为当连续n个单元被占用后,在散列到这些单元上的关键字和直接散列到后面一个空闲的单元上的关键字都要占用这个空闲单元,致使该空闲单元很容易被占用,从而发生非同以冲突。造成平均查找长度变长。

(2).平方探查法

设发生冲突的地址为d,则平方探测法的探查序列为:d+1^2, d+2^2,…直到找到一个空闲位置为止。

d0 = H(k)

di = (d0 + i^2) % (1 ≤ i ≤ m-1)

2.链地址法

用链地址法解决冲突的方法是:把所有关键字为同义词的记录存储在一个线性链表中,这个链表称为同义词链表。并将这些链表的表头指针放在数组中。

在这里插入图片描述

冲突原因与三个因素有关。

1.装填因子a(load factory)

a = 存储的个数 / 哈希表的大小。
a的值在0.6~0.9时产生的冲突最小

2.哈希函数

好的哈希函数计算出来的哈希值会均匀分布在哈希表的整个地址区间。从而减少冲突。

3.处理冲突的方法(与解决冲突的哈希冲突函数)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值