哈希表与一般查找方法的比较及冲突的解决

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2007 年 10 月 十 堰 职 业 技 术 学 院 学 报 Oct . ,2007 第 20 卷第 5 期 Jo urnal of Shiyan Technical Instit ute Vol . 20 No . 5
值得一提的是 ,哈希函数不是唯一的 ,我们可以根据要 存取数据的具体情况自己构造一个 。 2. 1 哈希表的应用举例
假设有这些关键字 :28 ,32 ,45 ,31 ,77。存放在 A (10) 这个数 组中 ,我们可构造这样的哈希函数 F (X) = X MOD 10 (这个 函数的意思为 X 对 10 求余 ,假如 X = 42 ,那么 F (X) = 2) ,那么 我们可知 F(28) = 8 ,F (32) = 2 ,F (45) = 5 ,F(31) = 1 ,F (77) = 7 , 而这些 8 ,2 ,5 ,1 ,7 就是这些关键字的存放地址。然后我们根据 这些地址将关键字存放在数组 A(10) ,图如下 :
— 96 —
哈希表与一般查找方法的比较及冲突的解决
我们要查找关键字 77 ,只需通过函数 F (77) = 7 ,就知 77 放
在数组 A 中下标为 7 的位置 。这样我们就可以不需要进行
任何比较就能很快地在表中找到相应的数据 。
2. 2 哈ቤተ መጻሕፍቲ ባይዱ函数的冲突
对不同的关键字可能得到同一个哈希地址 ,如上例的关
知道 ,顺序查找和折半查找的性能会随着数据量的增加而降 ( HX) ,提高按 ID 号查找某学生数据的速度 。
低 ,而用哈希表来查找是不会这样的 。
表 2 XS 表
行号 第1行 第2行 第3行
:
ID
姓名
2
黄秋燕
4
李翔
5
罗卓浪
:
:
身份证号 441702198609114440 441702198512191553 441702198606180338
键字中假设还有一个关键字为 22 ,那么 F (22) = 2 ,这正好与
关键字 32 的地址一样 F (32) = 2 ,这种现象称为冲突 。那么
22 这个新的数应放到哪里呢 ?
然而 ,在以住 ,我们都认为冲突只能尽可能地少 ,而不能
完全地避免 。
3 解决冲突的前提
任何方法的可行性都有前提 ,没有完全绝对的方法 。当
那么 ASL = 1 000/ N ,而当 N = 10 000 时 ,ASL = 0. 1 。从这
假设有以下学生表 ( XS) ,表中有 1 000 个学生记录 ,其
我们就可知道 ,当数据比较多的时候 ,一般的查找方法与我 中的 ID 号是关键字 ,并以升序排列 ,行号并非是表中的内
们的哈希表查找方法性能相差甚远 。并且从它们的 ASL 中 容 ,是用 来 帮 助 我 们 理 解 用 的 。现 为 它 建 立 一 个 哈 希 表
ASL = P1 ×1 + P2 ×2 + P3 ×3 + ……+ PN - 1 ×( N - 1) + PN ×N
假设每个记录的查找概率相等 : Pi = 1/ N 则在等概率情况下顺序查找的平均查找长度为
N
N
∑ ∑ ASL =
Pi Ci
i =1
=
1
i = (1 + N) / 2[1]
N i =1
对于含有 N 个记录的表 ,查找成功时的平均查找长度为
N
∑ ASL =
Pi Ci
i =1
其中 Pi 为查找表中第 i 个记录的概率 。Ci 为找到表中
其关键字与给定值相等的第 i 个记录时 ,和给定值已进行过
比较的关键字个数 。
从顺序查找可见 , Ci 取决于所查记录在表中的位置 。 如 :查找表中第一个记录时 ,仅需比较一次 ;第二个记录时 , 要两次 ……最后一个记时 ,要 N 次 ,一般情况下 Ci 等于 i 。
就拿顺序查找方法来看 ,假如表中有大量的数据 ,用这 个方法效率很低 ,最差的情况就是要查找的数据在表的最 后 ,这样就需要把所有的数据都读一遍 。而折半查找方法虽 然比顺序查找方法快很多 ,但对于大量数据来说 ,比较次数 也会随着数据的数量变大而增多 ,并且如果要查找的数据在 表的开始 ,反而这时的查找速度还不如顺序查找方法 。 1. 2 哈希表的提出
翻倍 。就从个人计算机的硬盘来说 ,从 2000 年的 20 G 容量
的硬盘到 2006 年的 200 G 硬盘 ,容量变化是 10 倍 ,但从计
算机的 CPU 来说 ,从 2000 年的 700 M Hz 的 CPU 到 2006
年 2. 2 GHz 的 CPU 来看 ,速度只提高了 3 倍 。那么我们是
序查找优胜 。
而用哈希表来查找 ,假如 Pi 仍然为 1/ N ,Ci 可以说是为 0 ,因为在查找过程中无需与任何关键字进行比较 。但现实 情况来说 ,由于哈希函数的计算需要时间 ,那么我们作最差
— 97 —
十堰职业技术学院学报
2007 年第 5 期
第 20 卷第 5 期
的打算 ,Ci = 1 000 (这个数已经被放大差不多 100 倍了) 。 4 应用举例
哈希表与一般查找方法的比较及 冲突的解决
骆剑锋
(广东技术师范学院 天河学院 计算机系 ,广东 广州 ,510540)
[ 摘 要 ] 众所周知 ,在表中查找记录时需进行查找值和关键字的比较 。这一类查找方法建立在“比较”的基础 上 。一般的查找方法有 :顺序查找 、折半查找 、二叉查找 。查找的效率依赖于查找过程中所进行的比较次数 ,甚 至有一些数据的位置会影响某一次查找效率 。理想的是希望不经任何比较 ,一次存取便能得到所需查找的记 录 。这个理想的情况可以通过哈希表来实现 。 [ 关键词 ] 哈希表 ;哈希函数 ;冲突 ;查找 ;关键字 [ 中图分类号 ] TP301. 6 [ 文献标识码 ] A [ 文章编号 ] 100824738 (2007) 0520096203
从上面的例子可知顺序查找方法效率不高 ,但是我们还 有其他查找方法 ,如 :折半查找 ,它是建立在数据存放有序的 基础上的 ,过程是 :先确定待查记录所在范围 ,然后逐步缩小 范围直到找到或找不到该记录为止 。这类似我们在书中找 某一页的过程 ,比如有一本非常厚的书 (3 000) ,要找到 1 076 页 ,我们一般会翻到书的中间 ,看一下当前页数为多少 , 假如是 1 400 页 ,那么你就会缩小查找的范围 (从第 1 页到 1 400 页) ,接着又在这个范围中用相同的方法找 。 1. 1 一般的查找方法存在的缺点
然数在存储时出现的冲突问题 。
以上只是解决冲突的一个例子 ,当然要在这作一下补充 和说明 :
(1) 从要存储的数据来看 ,数据越集中 ,哈希表就越小 。 但是 ,就算数据不集中 ,我们仍然可以用这种思想来存储数 据 ,只是可能造成不少储存空间的浪费 。
(2) 以上只是一种思想 ,哈希表不一定是一个 A (10 ,10) 的表 ,应该按照数据的范围来决定表的大小 。比如 ,上例的 数据可以用 A (7 ,7) 的二维数组来存储 。
3
1 一般查找方法的介绍
在现实生活中有不少查找数据的例子 ,如在学生成绩表中 查找某一学生的成绩 ;在集体宿舍的名单中找到某个人所在的 宿舍等 。前人已在这些现实的例子中找到不少适合用计算机去 查找的方法 ,如 :顺序查找、折半查找等。
最容易理解的莫过于按照顺序查找 ,它的查找过程为 : 从表中的第一个记录开始 ,逐个地进行记录的关键字和给定 值的比较 ,若某个记录的关键字和给定值的比较相等 ,则查 找成功 。反之 ,若直至最后一个记录 ,其关键字和给定值的 比较都不相等 ,则表明表中没有给定值 ,这种方法可用在学 生成绩表中查找某一学生的成绩 。
(4) 哈希表的行数与列数不一定相同 ,比如可建立 A (10 ,3) 这样的表 ,但要存储的数据的个位数就不能大于 3 了 。所以应先估计数据的范围 ,再去建立表 。 3. 2 性能分析
一个查找方法的好坏通常是以其关键字和给定值进行
比较过的记录个数的平均值来衡量的 。而平均查找长度
ASL (Average Search Lengt h) 就是进行比较的关键字个数 的期望值 。ASL 值越小 ,查找平均速度越快 。
然这里介绍的方法也有前提 :
第一 :要存放的数据要尽量集中 ,不能太过分散 ,如 : 7 ,
13 ,20 ,17 这些数据的数值差距不大 ,比较集中 。
第二 :需要计算机的储存容量比较大 。
第一个前提并非是绝对的 ,也就是说数据也可以分散 ,
但这就需要很大的计算机储存容量 。第二个前提的实现可
能不存在问题 ,当今计算机的储存硬件已经日新月异 ,容量
A
31 32
45
77 28
0123456789
图 1 A (10) 数组 数组 A (10) 就是由哈希函数 F ( X) 构成的哈希表 。假如
3 [ 收稿日期 ] 2007208230 [ 作者简介 ] 骆剑锋 (1981 - ) ,男 ,广东技术师范学院天河学院计算机系教师 、软件设计师 。
(3) 两个哈希函数 FX( X) = X MOD 10 和 F Y( Y) = IN T ( Y/ 10) 中的 10 不一定是 10 ,要根据要存储数据的范围和哈 希表的大小来决定 。其实哈希函数可以写成这样 : FX( X) = X MOD N 和 F Y( Y) = IN T ( Y/ N) ,N 就是哈希表的行数或 列数 ,取其中的较大者 。
从上面可知 ,顺序查找的性能取决于表的长度 ( N) ,表
越长 ,查找速度越慢 ,假如表有 10 000 个记录 ,那么它的平
均查找长度大约为 5 000 。
而折半查找的 ASL = [ log2 ( N + 1) ] - 1 ,假如表有 10
000 个记录 ,那么它的平均查找长度大约为 12 ,这明显比顺
作用是 :求 Y 的倍数 ,如 Y = 58 ,那么 F Y( Y) = 5) ,那么就可
以得到下表所示的地址 :
表 1 关键字转地址表
关键字 FY (关键字) 的值(行地址) FX (关键字) 的值(列地址)
25
2
5
32
3
2
22
2
2
45
4
5
66
6
6
也就是说 28 ,32 ,22 ,48 ,66 关键字分别存放在坐标为 (2 ,5)
(3 ,2) (2 ,2) (4 ,5) (6 ,6) 的 A (10 ,10) 二维数组中。如下图 :
图 2 A (10 ,10) 示意图
这样 ,二维数组 A ( 10 , 10) 就是由哈希函数 FX ( X) 和 F Y( Y) 构成的哈希表 ,假如要查找给定值 45 ,只需通过函数 F Y(45) = 4 和 FX(45) = 5 ,就知道 45 放在二维数组 A 中下 标为 (4 ,5) 的位置 。这样 ,我们就可以不需要进行任何的比 较就能在表中找到相应的数据 。这种存储方法可以解决自
不是应该多用点容量来换取我们的速度呢 ?
3. 1 冲突解决方案的提出
假设有这些关键字 :25 ,32 ,22 ,45 ,66 。用 A (10 ,10) 二
维数组作为存放关键字的哈希表 ,我们分别构造两个哈希函
FX( X) = X MOD 10 和 F Y( Y) = IN T ( Y/ 10) 。( F Y( Y) 的
从上面的方法来看 ,影响查找速度的关键因素是在查找
的过程中 ,记录的关键字和给定值的比较的次数 。所以可以 这样说 :比较的次数越多 ,查找时间越长 。理想的情况是希 望不经任何比较 ,一次存取便能得到所查找的记录 。而这个 理想的情况可以用哈希表和它的算法来实现 。
2 哈希表的概念
如果希望不经过任何比较 ,一次存取便能得到所查记 录 ,那就必须在记录的存储位置和它的关键字之间建立一个 确定的对应关系 F ,使每个关键字和唯一的存储位置相对 应 。因而在查找时 ,只要根据这个对应关系 F 就能找到给定 值 K 的像 F ( K) 。若表中存在关键字和 K 相等的记录 ,则必 定在 F ( K) 的存储位置上 。其实换个说法 ,就是通过函数 F () ,算出要查找关键字 K 的存储位置 F ( K) ,这样就实现了 不需要进行比较便可直接取得查找记录 。在此 ,我们称这个 对应关系 F 为哈希函数 ,按这个思路而建立的表为哈希表 。
相关文档
最新文档