梦想还是要有的,万一忘了咋办?

0%

哈希表

Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。

HASH函数

哈希函数并不通用,比如在数据库中能够获得很好效果的哈希函数,用在密码学或错误校验方面就未必可行。在密码学领域有几个著名的哈希函数。这些哈希函数包括MD2\MD4\MD5,利用散列法将数字签名转换成的哈希值称为信息摘要,另外还有安全散列算法(SHA),这是一种标准算法,能够生成更大的(64bit)的信息摘要,有点类似MD4算法。

余数法

取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p,p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生碰撞。

折叠法

针对原始值是数字时使用,将原始值分为若干部分,然后将各部分叠加,得到的最后四位数字(或者取其他位数字都可以)来作为哈希值

基数转换法

原始值为数字时,可以将原始值的数制基数转为一个不同的数字。例如,可以将十进制的原始值转化为十六进制的哈希值。为了使哈希值长度相同,可以省略高位数字。

数据重排法

这个方法只是简单的将原始值中的数据打乱排序。比如可以将第三位到第六位的数字逆序排列,然后利用重排后的数字作为哈希值。

冲突及解决

不同的key值产生相同的地址,H(k1)=H(k2)
比如除留余数法:表长3时,3、6、9 会产生hash冲突
压缩存储一定会带来冲突。

开放寻址法

Hi=(H(key)+di) MOD m,i=1,2,3…,k(k<m-1),其中H(key)为散列函数,m为散列表长,di为增量序列,可有一下三种取法:

  • di=1,2,3…,m-1,称线性探测再散列;
  • di=12,22,32,…k2(k<=m/2),称二次探测再散列
  • di=伪随机数序列,称为随机探测再散列。

再散列法

Hi=RHi(key),i=1,2,…,k RHi均是不同的散列函数,即在同义词产生地址冲突时计算另一个散列函数地址,直到冲突不再发生,这种方法不易产生”聚集“,但增加了计算时间。

链地址法(拉链法)

链地址法
冲突的key,以链表存放在一个区域。查找时遍历节点的所有对象,也可以为这些对象构建索引加速查询。

建立一个公共溢出区

把冲突的key 都放到一个区域,查找时遍历这个区域所有数据即可。也可以创建所以加速查询。

查找性能

  • 散列函数是否均匀
  • 处理冲突的方法
  • 散列表的装填因子
     装填因子定义:α=填入表中的元素个数/散列表的长度
    α是散列表装满程度的标志因子。由于表长是定值,α与”填入表中的元素个数“成正比,所以α越大,填入表中的元素较多,产生冲突的可能性就越大;α越小填入表中的元素较少产生冲突可能性越小。
    查找性能