对Hash表的一些见解

  记得是在大二上学习数据结构这一门课程时,高航老师向我们介绍了Hash表以及如何构造一个Hash表。如今我正准备找实习工作,而Hash表在实际应用中非常广泛,所以最近准备再次深入学习Hash表,并将这次所学记录在此博客。


一.什么是Hash表

	维基百科上是这样介绍Hash表的:	散列表Hash table,也叫哈希表),是根据关键字(Key value)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。

	个人理解为:通过构造一个散列函数(哈希函数),将 键-值 进行对应,达到一种非常快速、高效的查询数据的结构。这种结构是相较于普通的数据结构(如线性表、树等)来说,普通结构中记录的位置是随机的,和记录的关键字之间不存在确定的关系,所以在具体的查询操作的时候,需要一一进行关键字的比较,这样复杂度就大于O(1);而对于Hash表来说,只需知道"键"和散列函数就能立即知道"值"的位置,从而达到O(1)的复杂度。
	
关于Hash函数:
		Hash操作的本质即为将一个数据映射成另一个数据,通常情况下原数据容量大于映射后数据容量,这种映射关系我们称为Hash函数。


 

二.Hash表的构造方法

构造Hash表之前要先确定Hash函数。

在严蔚敏版的《数据结构》一书中,提出了6种构造方法,分别是:直接定址法、数字分析法、平方取中法、折叠法、除留余数法和随机数法。

三.Hash冲突

Hash冲突产生的原因

如果有有key值哈希之后对应的地址已经存放了数据,这种情况就被称为Hash冲突。如果有一个Hash函数使得每一个输入值都能对应唯一的一个储存单元(没有冲突),这个Hash函数就可以称为完美Hash函数。但实际情况中为了是Hash函数简单、运行速度快,往往不会采用完美哈希函数,所以肯定会冲突,为了减少冲突,我们希望哈希之后的结果能够均匀的存储在地址空间中,这样可以有效地减少冲突。

如何解决Hash冲突

在《数据结构》教材上,我们学习了4种解决办法,分别是:开放地址法、再哈希法、链地址法和建立公共溢出区。其中常用的办法是开放地址法和链地址法。
开放地址法
	基本思想是:哈希之后找到对应的存储单元,如发生冲突,则再通过某种方法探寻表中其他储存空间单元,直至找到可用的单元为止。
	Hi  = ( H(key) + di ) MOD m          i为下标,i = 1, 2,...,k (K <= M - 1)
	其中 H(key) 为哈希函数,m为哈希表表长, 
	di为增量序列,可有三种取法
		(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 = 伪随机数序列,称为伪随机探测再散列。
	
	例如:现在第i个空间已经被存放了M元素,又来了一个元素N,元素N哈希之后也应被分配到第i个单元,这时冲突发生:
	如果是线性探测再散列方法: 
			1.j = 1
			2.若第 (i+j) % m 个单元可用则存入
						3.若不可用,则 j++
						4. goto 2
	对于二次探测散列和伪随机探测再散列方法,只需改变上述个别步骤即可。
 
 
链地址法:
 
		基本思想:将所有哈希地址为i 的元素构成一个称为同义词链的链表,并将链表的头指针存在哈希表的第i个单元中,因而查找、插入和删除主要在同义词链中进行。 

链地址法是将数组和链表组合而成,如果发生冲突,只需将冲突元素加入其同义词的链表之中。

这里借用教材上的一张图片,应该很好理解。



两种方法对比:
链地址优势有:
		①链接法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;
		②由于链接法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;
		③开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而链接法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;
		④在用链接法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。而对开放地址法构造的散列表,删除结点不能简单地将被删结点的空间置为空,否则将截断在它之后填人散列表的同义词结点的查找路径。这是因为各种开放地址法中,空地址单元(即开放地址)都是查找失败的条件。因此在 用开放地址法处理冲突的散列表上执行删除操作,只能在被删结点上做删除标记,而不能真正删除结点。
开放地址法相较链地址法优势是:不需要用到额外空间。
 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值