算法与数据结构学习笔记(12):散列表查找(哈希表)

存储位置=f(关键字)

散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key)

f称为散列函数,又称为哈希(Hash)函数

采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间称为散列表或哈希表(Hash table)

散列主要是面向查找的存储结构

散列技术最适合的求解问题是查找与给定值相等的记录。不适合范围查找

哈希函数的构造方法

哈希函数的构造原则:计算简单,散列地址分布均匀

(1)直接定址法
适用于查找表较小且连续的情况(不常用)

方法:取关键字的某个线性函数值为散列地址
f(key) = a×key + b(a、b为常数)

优点:简单、均匀、不会产生冲突

(2)数字分析法
适用于处理关键字位数比较大的情况,事先直到关键字分布且关键字的若干位分布较均匀

方法:抽取关键字的一部分来计算散列存储地址

(3)平方取中法

适用于不知道关键字的分布,而位数又不是很大的情况。

方法:把关键字平方得到结果,再去结果的中间几位作为散列地址。

如关键字1234,它的平方是1522756,取中间的三位227作为散列地址。

(4)折叠法

适用于事先不知道关键字的分布,适合关键字位数较多的情况。

方法:将关键字从左到右分割成位数相等的几部分(若最后一部分位数不够可以短些),然后将这几部分叠加求和,并按散列表表长,取后几位作为散列地址。

如关键字为9876543210,散列表表长为3位,将关键字分为4组987|654|321|0,叠加求和987+654+321+0=1962,再取后三位962作为散列地址。

(5)除留余数法

散列函数为:f(key) = key mod p(p<=m)m是散列表长
mod是取模(求余)

该方法关键就是在p的选取。p最好接近m的最小质数或不包含小于20质因子的合数。

(6)随机数法
适用于关键字长度不等

方法:f(key)= random(key)

注:若关键字是字符串,都可以将这些关键字化为某种数字。

处理散列冲突的方法

两个关键字key1 != key2,但却有f(key1) = f(key2),这种现象叫冲突,并把key1和key2称为这个散列函数的同义词。

1.开放定地址法

(1)定义
一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入。

1、开放定址法(建立闭散列表)
开放定址指散列表的地址对任何记录数据都是开放的,即可存储使用。但散列表长度一旦确定,总的可用地址是有限的。闭散列表表长不小于所需存储的记录数,发生冲突总能找到空的散列地址将其存入。查找时,按照一种固定的顺序检索散列表中的相应项,直到找到一个关键字等于k或找到一个空单元将k插入,故是动态查找结构。

1)线性探测法

从发生冲突位置的下一个位置开始寻找空的散列地址。发生冲突时,线性探测下一个散列地址是:Hi=(H(key)+di)%m,(di=1,2,3…,m-1)。闭散列表长度为m。它实际是按照H(key)+1,H(key)+2,…,m-1,0,1,H(key)-1的顺序探测,一旦探测到空的散列地址,就将关键码记录存入。

该方法会产生堆积现象,即使是同义词也可能会争夺同一个地址空间,今后在其上的查找效率会降低。

2)二次探测法

发生冲突时,下一位置的探测采用公式:Hi=(H(key)+di)%m,(di=12,-12,22,-22,…,q2,-q2,q<=根号下m)

在一定程度上可解决线性探测中的堆积现象。

3)随机探测法

di为{1,2,3,…,m-1}中的数构成的一个随机数列中顺序取的一个数

4)再散列函数法

除基本散列函数外,事先设计一个散列函数序列,RH1,RH2,…,RHk,k为某个正整数。RHi均为不同的散列函数。对任一关键码,若在某一散列函数上发生冲突,则再用下一个散列函数,直到不发生冲突为止。

5)建立公共溢出区(单链表或顺序表实现)

另外开辟一个存储空间,当发生冲突时,把同义词均顺序放入该空间。若把散列表看成主表或父表,则公共的同义词表就是一个次表或子表。查找时,现在散列表中查,找不到时再去公共同义词子表顺序查找。

2、拉链法(链地址法、建立开散列表)
将所有散列地址相同的记录存储在同一个单链表中,该单链表为同义词单链表,或同义词子表。该单链表头指针存储在散列表中。散列表就是个指针数组,下标就是由关键码用散列函数计算出的散列地址。初始,指针数组每个元素为空指针,相当于所有单链表头指针为空,以后每扫描到一条记录,按其关键码的散列地址,在相应的单链表中加入含该记录的节点。开散列表容量可很大,仅受内存容量的限制。

例:具体的关键字列表为(19,14,23,01,68,20,84,27,55,11,10,79),则哈希函数为H(key)=key MOD 13。则采用除留余数法和链地址法后得到的预想结果应该为:

三、散列表上的查找
1、时间复杂度分析

查找成功时的平均查找长度ASLsucc、查找不成功时的平均查找长度ASLunsucc

1)具体闭散列表的查找效率分析

关键码{19,14,23,1,68,20,84,27,55,11,10,79},散列表长度m=16,除留余数法设计散列函数,H(key)=key%13,

(1)线性探测法处理冲突

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值