3 数据结构_Java集合_01(List Map)_辅助 hash算法

本文介绍了散列函数的基本概念,包括散列值、散列表和散列冲突的定义,并详细探讨了几种常见的冲突处理方法,如开放寻址法及再散列法。


1   Hash:译作"散列" 见名知道意(之前就傻乎乎的Hash Hash 都不知道啥是Hash )
      定义:把任意长度的输入,通过散列算法变换成固定长度的输出,该输出就是散列值.
       这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间.
       不同的输入可能有相同的散列值.
       
       散列值不同,关键字必不相同.
       
       
       散列函数与散列表:
                 若结构中存在和关键字K相等的记录,则必定在f(K)的存储位置上.(无需比较,直接得到所查询的记录.)
      ---此对应关系即为散列函数.
      
                 按照散列函数事先建立的表:::即为散列表
       碰撞:
                  不同的关键字可能得到同一散列地址,这种现象称为碰撞.即key1!=key2,f(key1)=f(key2)
      同义词:发生碰撞现象的关键字是同义词.相对于该散列函数来说.
      
       散列造表(散列)与散列地址:

                   根据散列函数+碰撞处理方法,将一组关键字,映射到一个有限的连续的地址集上,

                   并以关键字在地址集中的象,作为记录在表中的存储位置。

                   这种表:成为散列表
                   这个过程:成为散列造表
                   所得存储位置:散列地址
                   
        均匀散列函数:
                 任意关键字,经散列函数映象到地址集合中任何一个地址的概率是相等的,此函数则成为均匀散列函数.
                 
       冲突处理方法:
                开放寻址法:Hi=(H(key) + di) MOD m
             m,i=1,2,…,k(k<=m-1),其中H(key)为散列函数,m为散列表长,di为增量序列
                                      根据di取值不同,可以再分为3小种(按序 平方 随机)
               1). di=1,2,3,…,m-1,称线性探测再散列;
   2). di=1^2,(-1)^2,2^2,(-2)^2,(3)^2,…,±(k)^2,(k<=m/2)称二次探测再散列;
   3). di=伪随机数序列,称伪随机探测再散列。
   再散列法:调用另一个散列函数

2 相同的hashCode


规律:Aa===BB

        Bb===CC

        Cc===DD

类推





大家都知道equals()相同时 hashcode 必须相同 但是hashcode相同并不一定eqauls
但是具体的例子还真没看过
我们可以看到String 的 hashcode()方法如下

public int hashCode() {
        int var1 = this.hash;
        if (var1 == 0 && this.value.length > 0) {
            char[] var2 = this.value;

            for(int var3 = 0; var3 < this.value.length; ++var3) {
                var1 = 31 * var1 + var2[var3];
            }

            this.hash = var1;
        }

        return var1;
    }

这里我用我的姓的拼音来演示下 马(Ma)
在Ascii表中我们可以找到 Ma和编码分别是 77 66
这样算的就是(31*0+77)*31+66
数据有点少看不出来规律 再加上我的名 林(Lin) 76 69 110
这样算起来就是

((((31*0+77)*31+66)*31+76)*31+69)*31+110

这样我们就可以总结出来规律啦

31*31(n-1)+str.charAt(0)*31(n-2)+str.charAt(1)*31(n-3)+...+str.charAt(n-1)

其中的(n-*)代表根次方

这样我们就可以看出来了 如果构造相邻俩个最后的和一样
我们设比较的两个字符串的编码形式为 (x1)(y1)(x2)(y2)
他们俩只有中间俩个字符的编码不一样 那么怎么分别设置这两个字符串才能让他们的编码最后相同呢
经过一番高考之前的我附身 我们可以得到以下的等式

image

掘金和简书竟然都不支持公式……

最最重要的是

(x1-x2)*31=(y2-y1)

也就是相邻的两位如果前边的编码差 1 后边的两个的编码就要差 -31*1

俩个实例吧 还是上边的我的大姓 Ma
有哪个字符串是和 M(77)a(97) Hashcode相同的呢
其中一个结果竟然为 NB(敲黑板) N(78)B(66) 看起来我们这个姓比较厉害了



作者:马木木
链接:https://www.jianshu.com/p/44e878e987bf
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值