14 哈希表查找
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
【例1】已知连续的地址区间为0~6,给定关键字 k 的序列 {20 , 30 , 70 , 12 , 18} 。若将 k%7 的值 作为k的存储地址,则可以构造出以下存储结构。 地址:20%7=6;30%7=2;70%7=0;12%7=5;18%7=4
0 70 1 2 3 4 5 30 18 12 6 20
关键字 机内码 010203 ABC 020304 BCD 030405 CDE 040506 DEF ... ... 机内码的平方数 哈希地址 0104101209 101 0412252416 252 0924464025 1640739036 ... 464 739 ...
折叠移位法
若关键字的位数很多,且每一位上数字分布大
乔布斯:Windows又烂又慢,还经常死机啊! 盖茨:对啊。 乔布斯:那为什么不改进一下? 盖茨:改进了男生还怎么进女生宿舍修电脑?
1
上节回顾
二叉排序树的插入
三种可能 二叉排序树的查找 与根比较,三种结果 二叉排序树的删除 删除叶子结点 删除单支结点 删除双支结点
散列
什么是散列
同顺序存储结构和链式存储结构一样,散列也
【例1】已知连续的地址区间为0~6,给定关键字 k 的序列 {20 , 30 , 70 , 12 , 18} 。若将 k%7 的值 作为k的存储地址,则可以构造出以下存储结构。 其中,k%7就是用除留余数法设计的散列函数,7 是一个等于表长的素数。 地址:20%7=6;30%7=2;70%7=0;12%7=5;18%7=4
上例中k%7为散列(哈希)函数 ,构造出的存储结 构称为散列表。若添加新的关键字“14”,则其散 列函数值(14%7=0)将与关键字“70”的存储地址 相同,我们称这种关键字不同但是散列函数值相 同的现象为 冲突。在构造散列表的时候我们须同 时设计某种散列函数和某种处理冲突的方法。
散列函数的构造方法
15
59 34 22 20 35
链地址法
将所有关键字互为“同义词”的元素链接在一个线性链表 中。此时的散列表以“指针数组”的形式出现, “同义词” 链表按哈希地址在“指针数组”中存储链表的头指针。
{15,59,22,34,20,35} h(k)=k%l3
h(15)=15%13=2; h(59)=59%13=7; h(22)=22%13=9; h(34)=34%13=8; h(20)=20%13=7; h(35)=35%13=9;
0 70 1 2 3 4 5 30 18 12 6 20
数字分析法
如果可能出现的关键字的数位相同,且取值事
先知道,则可对关键字进行分析,取其中“分布
均匀”的若干位或它们的组合作为散列表的地址。
【例3】对如下一组关键字通过分析可知:每个关 键字从左到右的第l,2,3位和第6位取值较集中, 不宜作哈希地址。剩余的第4,5,7和8位取值较 分散,可根据实际需要取其中的若干位作为散列 地址。 关键字 散列地址
12 ^
70
15 ^
18 ^ 30 20 ^
8
63
19 ^
下节内容
排序
的平方值的中间若干位作为散列表的地址。 由于一个数的平方值的中间几位数受该数所有 位影响,将使随机分布的关键字得到的散列函 数值也随机 。 取关键字平方后的中间几位作为散列函数地址 (若超出表长范围时,可再取模)。
【 例 4】 设 有 一 组 关 键 字 ABC,BCD,CDE, DEF,……其对应的机内码如下表所示。假定地址 空间的大小为1000,编号为0-999。现按平方取中 法构造哈希函数,则可取关键字机内码平方后的 中间三位作为存储位臵。计算过程如下:
hi指冲突后尝试的下一地址(0 ≤ i ≤ m-1)
线性探查法 di= 1,2,3,…,m-1 平方探查法 di= i2
(0 ≤ i ≤ m-1)
双散列函数探查法
di= di+k2(k) (0 ≤ i ≤ m-1, d0=h(k))
【例 6】已知散列表长 13 ,地址区间 0 ~ 12 ,给定关键字 序列{15,59,22,34,20,35},散列函数h(k)=k%l3,采用 线性探查法处理冲突,试构造出散列表。 h(15)=15%13=2,存至A[2];h(59)=59%13=7,存至A[7]。 h(22)=22%13=9,存至A[9];h(34)=34%13=8,存至A[8]。 h(20)=20%13=7,冲突; h0 =7 h1 =(h0+1)%13=8,仍冲突; h2 =(h0+2)%13=9,仍冲突; h3 =(h0+3)%13=10,存至A[10]; h(35)=35%13=9,冲突;(同义词引起的冲突) h0 =9;h1=(h0+1)%13=10,仍(非同义词)冲突; h2 =(h0+2)%13=11,存至A[11]; 0 1 2 3 4 5 6 7 8 9 10 11 12
致均匀,则可采用移位叠加或间界叠加,即将
关键字分成若干部分,然后以它们的叠加和(舍 去进位)作为哈希地址。 移位叠加:将各段的最低位对齐相加; 间界叠加:两个相邻的段沿边界来回折叠对 齐相加。
【例5】已知关键字351246783,地址空间的大小 为1000,编号为0-999。用折叠移位法计算散列地 址的过程如下: 根据表长1000,将关键字分成3段,每段3位数字。 移位叠加的散列地址:351 246 +783 (1)380 (舍去进位) 间界叠加的散列地址:351
642
+wenku.baidu.com83 (1)776 (舍去进位)
处理冲突的方法
开放定址法
线性探查法
平方探查法
双散列函数探查法
链地址法
同义词:关键字不同而散列函数值相同的关键
字 冲突:待插入元素的散列地址单元已被占用, 该元素无法直接存入到此单元中。 冲突原因:散列地址区间小于关键字的取值区 间 装填因子α α 是已存入元素与散列空间大小的比例 一般取值为0.6-0.9时产生冲突的可能性较小 例如,若有元素600个,则选取表长为 667~1000较为合适。
1995 ...
查找举例:若要查1970年的出生人数,则根据散 列函数(1970-1948=22)计算散列地址,在表的 第22个位臵即可找到。
除留余数法
以关键字被某个整数m除后所得余数作为散列
地址。 h(k)=k % m (m<=表长) 使得数据集合中的每一个关键字通过该函数转 化后映射到哈希表的任意地址上的概率相等。 理论研究表明,在m取值小于或等于表长的为 素数时,冲突可能性相对较少。 常用方法,通常结合其它方法一起使用。
【例1】已知连续的地址区间为0~6,给定关键字 k 的序列 {20 , 30 , 70 , 12 , 18} 。若将 k%7 的值 作为k的存储地址,则可以构造出以下存储结构。 地址:20%7=6;30%7=2;70%7=0;12%7=5;18%7=4
0 70 1 2 3 4 5 30 18 12 6 20
h0 =8 h1 =(8+1)%11=9,冲突; h2 =(8+2)%11=10;
h(12)=12%11=l; h(18)=18%11=7; 0 1 2 3 4 5 6 7 8 9 10 63 12 19 70 15 18 30 20 8 散列表:
链地址法
h(20)=20%11=9; 散列表: 0 ^ 1 ^ h(30)=30%11=8; 2 ^ h(70)=70%11=4; 3 ^ h(15)=15%11=4; 4 ^ 5 ^ h(8)=8%11=8; 6 ^ h(12)=12%11=l; 7 ^ h(18)=18%11=7; 8 ^ h(63)=63%11=8; 9 ^ 10 ^ h(19)=19%11=8;
0 1 2 3 4 5 6 7 8 9 10 11 12
^ ^ ^ ^ ^ ^
15 ^
59 34 ^ 22
20 ^
35 ^
^ ^ ^
散列表上的查找
(1)根据待查找的数据元素x和建表时的散列函 数计算散列地址; (2)若该地址所对应的单元为空,则查找失败; 若不为空,则将该单元中结点的关键字与x 的关键字相比较; 若相等则查找成功; 若不相等,则按建表时设定的处理冲突的 方法找下一个地址。 (3)重复步骤(2),直至某个单元为空,查找 失败;或者与x的关键字相等,查找成功。
直接定址法
除留余数法
数字分析法
平方取中法
折叠移位法
直接定址法
取关键字本身或关键字的某个线性函数值作为
散列地址。 h(key)=key 或 h(key)=a×key+b (a 和 b 均为常数) 直接定址所得地址集的大小和关键字集的大小 相同,关键字和地址一一对应,决不会产生冲 突。但实际应用能采用直接定址的情况极少, 会造成存储空间的浪费, 适用于关键字基本连 续的情况。 例如,给定关键字序列{1,45,99}若采用h(k)=k 作为散列函数,则地址集为(1~99),但只存放3 个关键字,空间浪费严重。
【练习】已知散列表地址区间为 0 ~ 10 ,给 定关键字序列( 20 , 30 , 70 , 15 , 8 , 12, 18,63,19)。哈希函数为h(k)=k%ll,分 别采用线性探查法和链地址法处理冲突,构 造散列表。要求写出各自的计算过程并画出 对应的散列表。
线性探测法
h(20)=20%11=9; h(63)=63%11=8,冲突; h0 =8 h(30)=30%11=8; h1 =(8+1)%11=9,冲突; h(70)=70%11=4; h2 =(8+2)%11=10,冲突; h(15)=15%11=4,冲突;
h0=4 h1=(4+1)%11=5;
h3 =(8+3)%11=0; h0 h1 h2 h3 h4 h5
h(19)=19%11=8,冲突;
=8 =(8+1)%11=9,冲突; =(8+2)%11=10,冲突; =(8+3)%11=0,冲突; =(8+4)%11=1,冲突; =(8+5)%11=2。
h(8)=8%11=8,冲突;
是存储数据的一种方法,是将一组关键字映射 到一个有限的、地址连续的地址(区间)上。 散列存储的基本思路:以数据中每个元素的关 键字k为自变量,通过某种函数 H(k) 计算出函 数值,以该函数值作为一块存储空间的单元地 址,将该元素存储到函数值对应的单元中。 H(k) 称为散列函数或哈希(hash)函数。 把如此构造的线性表存储结构称为散列表或哈 希表。
【例2】统计某地区从1949年到1995年每年出生的 人数,列在一张表中。年份为关键字,因共有 47 年,所以表中位臵范围是1~47。 用直接定址法设臵散列函数 h(k)=k-1948 ,其中 k 为年份数。这样的散列表示意如下:
1 年份 人数 2 ... ... 47
1949 ...
1950 ...
923 17 6 02 923 26 8 75 927 39 6 28 923 43 6 34 927 06 8 16 927 74 6 38 923 81 2 62 2 75 28 34 16 38 62
平方取中法
如果关键字的所有各位分布都不均匀或较分散
的位数小于散列地址所需位数,则可取关键字
若 添 加 新 的 关 键 字 “ 14” , 则 其 散 列 函 数 值 (14%7=0)将与关键字“70”的存储地址相同,产 生冲突。此时14和70称为同义词。
开放定址法
使用某种探查技术,在散列表中形成一个探查序
列,当冲突发生时,沿此序列逐个单元查找空闲 单元地址。
hi=( h(k)+ di )%m