哈希表详解

最近在作负荷分担的优化,将数据流均匀分到八条流中,学习点哈希算法算法

什么是哈希表?
     哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它经过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫作散列函数,存放记录的数组叫作散列表。说白了哈希表的原理其实就是经过空间换取时间的作法。。
     哈希表的作法其实很简单,就是把Key经过一个固定的算法函数既所谓的哈希函数转换成一个整型数字,而后就将该数字对数组长度进行取余,取余结果就看成数组的下标,将value存储在以该数字为下标的数组空间里。
     而当使用哈希表进行查询的时候,就是再次使用哈希函数将key转换为对应的数组下标,并定位到该空间获取value,如此一来,就能够充分利用到数组的定位性能进行数据定位。。数组

哈希函数的构造方法:    数据结构

若对于关键字集合中的任一个关键字,哈希函数映像到地址集合中任何一个地址的几率是相等的,则称此类哈希函数为均匀的哈希函数。换句话说,就是使关键字通过哈希函数获得一个“随机的地址“,以便使一组关键字的哈希地址均匀分布在整个地址区间中,从而减小冲突。
(1)直接定址法
  取关键字或关键字的某个线性函数值为哈希地址。即: H(key)=key或H(key)=a*key+b; 其中a和b为常数(这种哈希函数叫作自身函数)。
因为直接定址所得地址集合和关键字集合的大小相同。所以,对于不一样的关键字不会发生冲突。但实际中使用这种哈希函数的状况不多。
(2)数字分析法
  假设关键字是以r为基的数(如:以10为基的十进制数),而且哈希表中可能出现的关键字都是事先知道的,则可取关键字的若干数位组成哈希地址。
(3)平方取中法
  取关键字平方后的中间几位为哈希地址。
(4)斐波那契(Fibonacci)散列法
     平方散列法的缺点是显而易见的,因此咱们能不能找出一个理想的乘数,而不是拿value自己看成乘数呢?答案是确定的。
     1)对于16位整数而言,这个乘数是40503 
     2)对于32位整数而言,这个乘数是2654435769 
     3)对于64位整数而言,这个乘数是11400714819323198485
     这几个“理想乘数”是如何得出来的呢?这跟一个法则有关,叫黄金分割法则,而描述黄金分割法则的最经典表达式无疑就是著名的斐波那契数列,即如此形式的序列:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946,…。另外,斐波那契数列的值和太阳系八大行星的轨道半径的比例出奇吻合。
     对咱们常见的32位整数而言,公式: index = (value * 2654435769) >> 28
(5)折叠法
  将关键字分割成位数相同的几部分(最后一部分的位数能够不一样),而后取这几部分的叠加和(舍去进位)做为哈希地址,这方法称为折叠法。
(6)除留余数法(==最经常使用的方法)
  取关键字被某个不大于哈希表表长m的数p除后所得余数为哈希地址。即H(key)=key MOD p,(p<=m),这是一种最简单,也是最经常使用的构造哈希函数的方法。它不只能够对关键字直接取模(MOD),也可在折叠、平方取中等运算以后取模。
(7)随机数法
  选择一个随机函数,取关键字的随机函数值为它的哈希地址,即H(key)=random(key),其中random为随机函数。一般,当关键字长度不等时采用此法构造哈希函数较切当。
总结:
  实际工做中需视不一样状况采用不一样的哈希函数,一般,考虑的因素有:
  (1)计算哈希函数所需时间(包括硬件指令的因素);
  (2)关键字的长度;
  (3)哈希表的大小;
  (4)关键字的分布状况;
  (5)记录的查找频率。dom

处理冲突的方法(冲突只能减小,不能避免):
  (1)开放定址法
  (2)再哈希法
  (3)链地址法
  (4)创建一个公共溢出区
哈希表的查找及其分析:
  在哈希表上进行查找的过程和哈希造表的过程基本一致。给定的K值,根据造表时设定的哈希函数求得哈希地址,若表中此位置上没有记录,则查找不成功;不然必将关键字,若和给定的值相等,则查找成功;不然根据造表时设定的处理冲突的方法找”下一地址“,直至哈希表中的某个位置为”空“或者表中所填记录的关键字等于给定值时为止。 
  哈希表的装填因子定义为:
                               α=(表中填入的记录数)/(哈希表的长度)函数

相关文章
相关标签/搜索