哈希表 哈希函数 哈希冲突

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

前言

一、哈希表是什么?

二、什么是哈希函数?

1.除留余数法(常用)

2.折叠法

3.平方取中法

4.数字分析法

5.直接定址法

三.哈希冲突

1.什么是哈希冲突?

2.如何解决

开放定制法:

链地址法:(常用)

rehash:

扩容的时机:

四.哈希表的查找效率

五.链地址法和开放定址法比较

六.删除数据

总结


前言

        不同于树的存储结构,哈希表是一种基于键值对的存储表,不需要由根节点向下比较,而是直接找到查询值得位置,查询可达O(1)


一、哈希表是什么?

哈希表是一种基于哈希函数的存储表,查询可达O(1).

相较于数组和链表,哈希表有什么优势?

数组是一种连续的地址结构,特点是便于查询,不利于插入和删除;

链表是一种不连续的地址结构,特点是便于插入和删除,不利于查询。

哈希表则是查询也快,又便于查找和删除,结合了数组和链表的使用。

二、什么是哈希函数?

      通过某种算法将key值转换成index的值,这样在查找key的时候可以直接通过哈希算法找到对应位置,而不像数组或树需要比较,查询可达O1。

方法简述:

1.除留余数法(常用)

H(key)=key MOD p (p<=m m为表长)

        该方法重点在于p的选择,根据前人经验,p应为不大于表长的质数或是不含20以下的质因子的合数,这样可以减少地址的重复(冲突)

例子:比如key为7,10,13,15,22,表长为6,则p取5.

index0123456
key1071322(冲突后移)

2.折叠法

如果数字的位数很多,可以将数字分割为几个部分,取他们的叠加和作为hash地址
使用
比如key=123 456 789
我们可以存储在61524,取末三位,存在524的位置
该方法适用于数字位数较多且事先不知道数据分布的情况

3.平方取中法

        如果关键字的每一位都有某些数字重复出现频率很高的现象,可以先求关键字的平方值,通过平方扩大差异,而后取中间数位作为最终存储地址。

比如key=1234 1234^2=1522756 取227作hash地址
比如key=4321 4321^2=18671041 取671作hash地址
这种方法适合事先不知道数据并且数据长度较小的情况


4.数字分析法

       假设关键字集合中的每个关键字key都是由s位数字组成,分析key中的全体数据,并从中提取分布均匀的若干位或他们的组合构成全体。


        我们知道身份证号是有规律的,现在我们要存储一个班级学生的身份证号码,假设这个班级的学生都出生在同一个地区,同一年,那么他们的身份证的前面数位都是相同的,那么我们可以截取后面不同的几位存储,假设有5位不同,那么就用这五位代表地址。
H(key)=key%100000
此种方法通常用于数字位数较长的情况,必须数字存在一定规律,其必须知道数字的分布情况,比如上面的例子,我们事先知道这个班级的学生出生在同一年,同一个地区。


5.直接定址法


        哈希函数为关键字的线性函数如 H(key)=a*key+b
这种构造方法比较简便,均匀,但是有很大限制,仅限于地址大小=关键字集合的情况。

三.哈希冲突

1.什么是哈希冲突?

不同的key值通过函数计算得出的index相同

2.如何解决

开放定制法:

函数:Hi​=(H(key)+di​)MODm

di的取值方法:

1.线性探测再散列

di=c*i

举例:

 缺点:某些点冲突太多,后移很多次,导致查询时要多次比较,效率降低

2.平方探测再散列

di=1^2,-1^2,2^2,-2^2,3^2.......

        研究表明:当表的长度为质数且表装载因子a不超过0.5时,新的表项一定能够插入,而且任何一个位置都不会被探查两次。因此只要表中有一半的空位置,就不会存在表满的问题。在搜索时可以不考虑表装满的情况,但在插入时必须确保表的装载因子a不超过0.5,如果超出必须考虑增容。
因此:平方散列最大的缺陷就是空间利用率比较低,这也是哈希的缺陷。
 

3.随机探测在散列

     一组随机数列

链地址法:(常用)

        这样就结合了数组以及链表的使用,通过哈希算法将key转成index值,如果冲突则在数组后接上链表,储存冲突的key的value,链表采用头插法,因为新插入的值大概率会再次使用,这样方便查找

rehash:

       当冲突过多,就会造成链很长,慢慢的效率也就降低了,这时需要我们对哈希表进行扩容了,一般扩大到原来的二倍,并重新选择p的值。

扩容的时机:

       对于哈希表的存储能力,设定了装载因子:所有元素个数/数组长度,一般将这个值设置为0.75作为临界值,超过则进行扩容。

四.哈希表的查找效率

      决定hash表查找的ASL因素:
      1)选用的hash函数
      2)选用的处理冲突的方法
      3)hash表的饱和度,装载因子 α=n/m(n表示实际装载数据长度 m为表长)
      一般情况,假设hash函数是均匀的,则在讨论ASL时可以不考虑它的因素hash表的ASL是处理冲突方法和装载因子的函数


五.链地址法和开放定址法比较

       开放地址法需要保持大量的空间以位置查找效率,而链地址法虽然需要储存链接指针,但更省空间,并且链地址法更利于插入和删除。

六.删除数据

        对于链地址法可以直接删除数据,而开放定址法不可以,应删除后在原有位置填入不存在的数据。


总结

        哈希表重点在于哈希函数的选择以及如何解决哈希冲突问题,这是影响其查找效率的主要因素,哈希函数常用除留余数法,解决哈希冲突常用链地址法。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BlackMonkeyHH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值