什么是哈希表?

简介

哈希表本质上是根据关键码值(Key value)而直接进行访问的数据结构,关键码是通过数据本身用某些规则处理找到的一个储存位置。数据将直接通过关键码存入数组,而取出也直接通过关键码取出。这种结构普遍用数组+链表,或数组+二叉树组成。通过哈希表可以大大加快查找数据的速度。就拿数组+链表的结构来说,其本质就是一个装了N个链表的数组,根据某些规则(取址)将数据存入不同的链表中,将本来一个巨大列表的查询量,分摊到各个小的链表中,从而增加查询速度。

哈希表的结构

哈希表的实现有很多方式,本例拿数组+链表例举。通过一个数组存取多个链表,然后将数据根据一些规则存入不同的链表中。当我们要查询某个数据时,可直接根据规则定位该列表,再进行查找。如果有20个链表,那么相较于没有哈希表的数组来说就减轻了19倍的查找压力。

原数据

数组
数据1
数据2
数据3
数据4
数据5
数据6
数据7
数据8
数据9

现在将其存入哈希表。准备一个数组,数组里面存入链表,每个链表存入若干个数据。一般会通过某些规则决定存入哪个链表,取出时也会根据这个规则获取,比如取余法。这里采用的是对数据的序号除3,如果小于1就存入第一个链表,大于1小于2则存入第二个链表,大于2则存入第三个链表。具体如下

数组链表头子节点子节点
下标0数据1数据2数据3
下标1数据4数据5数据6
下标2数据7数据8数据9

如果在原数组查询数据9,我们可能需要查9次。如果转换成哈希表,或许只需要4次,一次定位链表位置,三次查找具体值。

地址定位(如何选择存入哪个链表?)

其实常用的“定址”的手法有“五种”:

1)直接定址法
  很容易理解,key=Value+C;这个“C"是常量。Value+C其实就是一个简单的哈希函数。

2)除法取余法
  key=value%C
C为常数
3)数字分析法
  这种蛮有意思,比如有一组value1=112233,value2=112633, value3=119033,针对这样的数我们分析数中间两个数比较波动,其他数不变。那么我们取key的值就可以是key1=22,key2=26,key3=90。
4)平方取中法
  在关键字的平房里取中间的几个数值作为key
  比如:关键字:1234,关键字的平方:1522756,哈希函数值:227
5)折叠法
  举个例子,比如value=135790,要求key是2位数的散列值。那么我们将 value变为13+57+90=160,然后去掉高位“1”,此时key=60

哈希冲突

刚刚提到用某些规则决定存入到哪个链表,很多时候这个规则必然会存在一些问题,比如我两个不同的数据序号,却定位到了同一个表上(当然本例没有这种情况,本例也是一种解决冲突的方法),这种情况叫做哈希冲突,哈希冲突不可避免,只能尽量减少。

解决哈希冲突

开放地址法

线性探查再散列

假定取哈希的方式为取余法,有n=1,2,3……,m-1,这个n会不断递增,直到找到合适哈希值为止。

一般形式: 新的哈希值=(冲突的哈希值+n)%取余的值

举个例子:47和69对11取余都等于3,显而易见他们产生了冲突。那么就可以带入公式为69寻找新的哈希值,新的哈希值=(3+1)%11,新的哈希值为4。如果依然冲突,就将n不断递增,直到找到新哈希值,比如5=(3+2)%11。

单链表法

单链表法就是上文所展示的方法,一个哈希值存入一个链表,那么即便有哈希冲突也能存入不同的数据。

结语

并未做专业描述,这里简要介绍了一下哈希表的结构。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值