hash算法的底层实现逻辑及冲突的解决方式

很多小伙伴面试时,会碰到面试官问到如何解决哈希冲突的问题,要理解哈希冲突,首先要弄清楚hash函数和hash表(散列); 

 一、哈希表

    hash函数:所谓hash函数其实就是指一类加密算法(MD5/SHA等),将任意长度的输入变换为固定长度的输出的不可逆的单向密码体制,即index=Hash(key);

    简单的讲,hash函数就是根据key值计算出数据应该存放的地址,而哈希表则是基于哈希函数建立的一种查找表;

二、常见hash函数的构造方法

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

    2、数字分析法:假设关键字集合中的每个关键字key都是由s位数字组成(key1,key2,key3,....,keyn),分析key中的全体数据,并从中提取分布均匀的若干位或他们的组合构成全体;

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

    4、折叠法:如果数字的位数很多,可以将数字分割为几个部分,取他们的叠加和作为hash地址;

    5、除留余数法:H(key)=key MOD p (p<=m m为表长)

三、hash冲突的常见解决方案

   不论hash函数设计的如何巧妙,总会有特殊的key导致hash冲突,即H(key1)=H(key2),特别是对动态查找表来说,为了解决此类冲突,有以下几种方案:

  1、开放定址法(开放寻址法):

首先有一个H(key)的哈希函数
       如果H(key1)=H(keyi)
       那么keyi存储位置Hi=(Hash(key)+di) MOD m   (m为hash表长度)
       di通常有三种取法:

1)线性探测再散列:di​=c∗i

2) 平方探测再散列:di = 1^2,-1^2,2^2,-2^2....

3) 随机探测再散列(双探测再散列):di​是一组伪随机数列

    2、链地址法:

产生hash冲突后在存储数据后面添加一个指针,指向后面冲突的数据,如下所示:

    3、公共溢出区法:建立一个特殊存储空间,专门存放冲突的数据,此种方法适用于数据和冲突较少的情况

    4、再hash法(再散列法):准备若干个hash函数,如果使用第一个hash函数发生了冲突,则换一个hash函数,以此类推...

hash函数设计的考虑因素

1.计算散列地址所需要的时间(即hash函数本身不要太复杂)
2.关键字的长度
3.hash表的长度
4.关键字分布是否均匀,是否有规律可循
5.设计的hash函数在满足以上条件的情况下应尽量减少冲突

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值