散列表

散列表 又叫 哈希表 (hash table)。经过访问key而直接访问存储的value值。它的key - value之间存在一个映射函数,咱们能够经过key值和“看不到”的映射函数(散列函数)访问对应的value值。这加快了查找的速度!存放记录的数组称作散列表。散列方法不一样于顺序查找、二分查找、二叉排序树及B-树上的查找。它不以关键字的比较为基本操做,采用直接寻址技术 (就是说,它是直接经过key映射[映射函数,实现的方式有多种] 到内存地址上去的)。在理想状况下,无须任何比较就能够找到待查关键字,查找的指望时间为O(1)(面试的时候犯了这个错误)。php

 

举个形象的例子来讲:为了查找电话簿中某人的号码,能够建立一个按照人名首字母顺序排列的表(即创建人名x到首字母F(x)的一个函数关系),在首字母为W的表中查找“王”姓的电话号码,显然比直接查找就要快得多。这里使用人名做为关键字,“取首字母”是这个例子中散列函数的函数法则F(),存放首字母的表对应散列表。关键字和函数法则理论上能够任意肯定。[维基百科]面试

 

散列表
     设全部可能出现的关键字集合记为U(简称全集)。实际发生(即实际存储)的关键字集合记为K(|K|比|U|小得多)。
     散列方法是使用函数h将U映射到表T[0..m-1]的下标上(m=O(|U|))。这样以U中关键字为自变量,以h为函数的运算结果就是相应结点的存储地址。从而达到在O(1)时间内就可完成查找。
  其中:
     ① h:U→{0,1,2,…,m-1} ,一般称h为散列函数(Hash Function)。散列函数h的做用是压缩待处理的下标范围,使待处理的|U|个值减小到m个值,从而下降空间开销。
     ② T为散列表(Hash Table)。
     ③ h(Ki)(Ki∈U)是关键字为Ki结点存储地址(亦称散列值或散列地址)。
     ④ 将结点按其关键字的散列地址存储到散列表中的过程称为散列(Hashing)
数组

咱们基本知道了value和key之间存在一个映射关系h,简单的表示为 value = h(key)。 咱们会有疑问,函数以容许多对一出现的,也就是说,当多个key对应一个value时怎么办?安全

这就是散列表中的冲突。分布式

散列表的冲突现象
(1)冲突
     两个不一样的关键字,因为散列函数值相同,于是被映射到同一表位置上。该现象称为冲突(Collision)或碰撞。发生冲突的两个关键字称为该散列函数的同义词(Synonym)。
   【例】上图中的k2≠k5,但h(k2)=h(k5),故k2和K5所在的结点的存储地址相同。

(2)安全避免冲突的条件
     最理想的解决冲突的方法是安全避免冲突。要作到这一点必须知足两个条件:
①其一是|U|≤m
其二是选择合适的散列函数
     这只适用于|U|较小,且关键字均事先已知的状况,此时通过精心设计散列函数h有可能彻底避免冲突。

(3)冲突不可能彻底避免
     一般状况下,h是一个压缩映像。虽然|K|≤m,但|U|>m,故不管怎样设计h,也不可能彻底避免冲突。所以,只能在设计h时尽量使冲突最少。同时还须要肯定解决冲突的方法,使发生冲突的同义词可以存储到表中。

函数

构造散列函数spa

 

(直接复制的维基百科,详细可参见[1]) 散列函数能使对一个数据序列的访问过程更加迅速有效,经过散列函数,数据元素将被更快定位。设计

 

  1. 直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即hash(k)=khash(k)=a\cdot k + b,其中a\,b为常数(这种散列函数叫作自身函数)
  2. 数字分析法:假设关键字是以r为基的数,而且哈希表中可能出现的关键字都是事先知道的,则可取关键字的若干数位组成哈希地址。
  3. 平方取中法:取关键字平方后的中间几位为哈希地址。一般在选定哈希函数时不必定能知道关键字的所有状况,取其中的哪几位也不必定合适,而一个数平方后的中间几位数和数的每一位都相关,由此使随机分布的关键字获得的哈希地址也是随机的。取的位数由表长决定。
  4. 折叠法:将关键字分割成位数相同的几部分(最后一部分的位数能够不一样),而后取这几部分的叠加和(舍去进位)做为哈希地址。
  5. 随机数法
  6. 除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即hash(k)=k \,\bmod \,pp\le m。不只能够对关键字直接取模,也可在折叠法平方取中法等运算以后取模。对p的选择很重要,通常取素数或m,若p选择很差,容易产生碰撞。

 

查找效率

散列表的查找过程基本上和造表过程相同。一些关键码可经过散列函数转换的地址直接找到,另外一些关键码在散列函数获得的地址上产生了冲突,须要按处理冲突的方法进行查找。在介绍的三种处理冲突的方法中,产生冲突后的查找仍然是给定值与关键码进行比较的过程。因此,对散列表查找效率的量度,依然用平均查找长度来衡量。xml

查找过程当中,关键码的比较次数,取决于产生冲突的多少,产生的冲突少,查找效率就高,产生的冲突多,查找效率就低。所以,影响产生冲突多少的因素,也就是影响查找效率的因素。影响产生冲突多少有如下三个因素:blog

  1. 散列函数是否均匀;
  2. 处理冲突的方法;
  3. 散列表的载荷因子(load factor)。

 

参考:【1】维基百科  散列表 http://zh.wikipedia.org/zh-cn/%E5%93%88%E5%B8%8C%E8%A1%A8 

   【2】维基百科  分布式散列表 http://zh.wikipedia.org/zh-cn/%E5%88%86%E6%95%A3%E5%BC%8F%E9%9B%9C%E6%B9%8A%E8%A1%A8

相关文章
相关标签/搜索