数据结构与算法分析之哈希表(HashTable,又称散列表)--理论篇

哈希表的定义

哈希表就是一个集合A到另一个集合B的映射
A->B;
人->身份证;
上面的映射关系,在哈希表中,上述对应过程就称为hashing。A中元素a对应B中元素b,a称之为键值(key), b被称之为a的hash值(hash value)。

哈希函数

映射在数学上相当于一个函数f(x):A->B;哈希表的核心就是哈希函数,这个函数规定了集合A中的元素如何对应到集合B中的元素。

Hash函数的设计直接影响到对Hash表的操作效率,在构造Hash函数时尽量考虑关键字的分布特点来设计函数使得Hash地址随机均匀第分布在整个地址空间当中。通常有以下几种构造Hash函数的方法:

  • 直接定址法
    取关键字或者关键字的某个线性函数为Hash地址,例如:学生的学号是从2000开始,到4000,则可以将address(key)=key-2000;作为Hash地址。

  • 平方取中法
    对关键字进行平方运算,然后取结果的中间几位作为Hash地址。例如有以下关键字序列{421,423, 436},平方之后的结果为{177241, 178929, 190096},那么可以取{72,89,00}作为地址。

  • 折叠法
    将关键字拆分成几个部分,然后将这几个部分组合在一起,以特定的方式进行转化形成Hash地址。例如:图书的编号是8903-241-23,可以地址address(key)=89+03+24+12+03作为地址。
  • 除留取余法
    如果知道Hash表的最大长度为m,可以取不大于m的最大质数p,然后对关键字进行取余运算,address(key)=key%p。在这里的p选取非常关键,p选择一般取不大于m的最大质数。
  • 数字分析法
    假设关键字是以r为基的数,并且哈希表中可能出现的关键字都是事先知道的,则可取关键字的若干数位组成哈希地址。如手机号的后四位。
  • 随机数法
    选择一个随机函数,取关键字的随机函数值为它的哈希地址,即:H(key)=random(key)。常用在关键字长度不等时。

Hash冲突

哈希表的冲突表示键值和地址出现重复映射关系,主要处理方法有:开放寻址法,再哈希法,链地址法和建立一个公共溢出区四种方法。

1.开发定址法
这种方法也称再散列法,其基本思想是:当关键字key的哈希地址p=H(key)出现冲突时,以p为基础,产生另一个哈希地址p1,如果p1仍然冲突,再以p为基础,产生另一个哈希地址p2,…,直到找出一个不冲突的哈希地址pi ,将相应元素存入其中。这种方法有一个通用的再散列函数形式:Hi=(H(key)+di)%m i=1,2,…,n,其中H(key)为哈希函数,m 为表长,di称为增量序列。增量序列的取值方式不同,相应的再散列方式也不同。主要有以下三种:

(1) 线性探测再散列–最常用的方法
di=1,2,3,…,m-1;
这种方法的特点是:冲突发生时,顺序查看表中下一单元,直到找出一个空单元或查遍全表。

(2) 二次探测再散列
di=1^2,-1^2,2^2,-2^2,…,k^2,-k^2 ( k<=m/2)
这种方法的特点是:冲突发生时,在表的左右进行跳跃式探测,比较灵活。

(3) 伪随机探测再散列
di=伪随机数序列。

具体实现时,应建立一个伪随机数发生器,(如i=(i+p) % m),并给定一个随机数做起点。

举例说明:
例如,已知哈希表长度m=11,哈希函数为:H(key)= key % 11,则H(47)=3,H(26)=4,H(60)=5,假设下一个关键字为69,则H(69)=3,与47冲突。

线性探测再散列法:
下一个哈希地址为H1=(3 + 1)% 11 = 4,仍然冲突,再找下一个哈希地址为H2=(3 + 2)% 11 = 5,还是冲突,继续找下一个哈希地址为H3=(3 + 3)% 11 = 6,此时不再冲突,将69填入5号单元。
二次探测再散列法:
下一个哈希地址为H1=(3 + 12)% 11 = 4,仍然冲突,再找下一个哈希地址为H2=(3 - 12)% 11 = 2,此时不再冲突,将69填入2号单元。
伪随机探测再散列法:
且伪随机数序列为:2,5,9,……..,则下一个哈希地址为H1=(3 + 2)% 11 = 5,仍然冲突,再找下一个哈希地址为H2=(3 + 5)% 11 = 8,此时不再冲突,将69填入8号单元。

分析:线性探测再散列的优点是:只要哈希表不满,就一定能找到一个不冲突的哈希地址,而二次探测再散列和伪随机探测再散列则不一定。

2.再哈希法
3.链地址法
4.建立公共溢出区
这几种解决冲突的方法在本文就不具体描述了,详细解释可见参考文章。

转载地址:
http://blog.csdn.net/liufei_learning/article/details/19220391
特别鸣谢~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值