《数据结构与算法分析》课件第7章_第1页
《数据结构与算法分析》课件第7章_第2页
《数据结构与算法分析》课件第7章_第3页
《数据结构与算法分析》课件第7章_第4页
《数据结构与算法分析》课件第7章_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第7章索引结构与散列技术7.1索引结构7.2散列技术

7.1索引结构

7.1.1线性索引

1.线性索引的定义

对于索引非顺序结构,由于数据表中的记录是无序的,因此必须为每个记录建立一个索引项。这种一个索引项对应数据表中一个对象的索引结构称为稠密索引,如图7-1所示。图7-1学生数据表的稠密索引结构例如,图7-2就是满足上述要求的存储结构,其中,表R只有18个记录,被分成3块,每块中有6个记录;第一块中最大关键字22小于第二块中最小关键字24;第二块中最大关键字48小于第三块中最小关键字49。图7-2分块有序表的索引存储结构

2.多级索引

若数据表中的记录数n很大,索引表也很大,在内存中放不下时,需要分批多次读取外存才能把索引表搜索一遍。在这种情况下,可以建立索引的索引,称为二级索引,如图7-3所示。二级索引可以常驻内存。在二级索引中,一个索引项对应一个索引块,用于登记该索引块的最大关键字及该索引块的存储地址。在搜索时,先在二级索引中搜索,确定索引块地址;再把该索引块读入内存,确定数据结点的地址;最后读入该数据结点。图7-3二级索引结构的示例7.1.2倒排表

在对含有大量记录的数据表进行检索时,最常用的是针对记录的主关键字(关键字)建立索引,如图7-1中的“学号”。因为每个学生的学号不会重复,所以用它作为关键字可以保证在检索时能够找到唯一的对象。

但是,在实际应用中有时需要针对其他属性进行检索。例如,查询如下的学生信息:

(1)列出所有籍贯为陕西的学生名单。

(2)列出所有的女生名单。图7-4次索引示例

7.2散列技术

7.2.1散列表的概念

散列(Hashing)是一种重要的存储方法,也是一种常见的查找方法。散列的基本思想是:以结点的关键字k为自变量,通过一个确定的函数关系f,计算出对应的函数值,把这个函数值解释为结点的存储地址,将结点存入f(k)所指示的存储位置上,在查找时再根据要查找的关键字,用同样的函数计算地址,然后到相应的单元里读取。

例7-1

假设要建立一张全国30个地区各民族人口统计表,每个地区为一个记录,记录的各数据项为

显然,可用一个一维数组R[30]来存放这张表,其中R[i] 是编号为i地区的人口情况,那么编号i便为记录的关键字,由它唯一地确定记录的存储位置R[i]。

例7-2

已知一个含有70个结点的线性表,其关键字都由两位十进制数字组成,则可将此线性表存储在做如下说明的散列表中:

datatypeHT1[100]

其中,HT1[i]用于存放关键字为i的结点,即散列函数为

H1(key) = key

(7-1)

例7-3

已知线性表的关键字集合为

S={and,begin,do,end,for,go,if,repeat,then,until,while}

则设散列表为

charHT2[26][8]

散列函数H2(key)的值取关键字key中第一个字母在字母表{a,b,

,z}中的序号(序号范围是0至25),即

H2(key) = key[0]

‘a’(7-2)

其中,key的类型是长度为8的字符数组。利用散列函数H2构造的散列表如表7-1所示。综上所述,散列法查找必须解决下面两个主要问题:

(1)选择一个计算简单且冲突尽量少的“均匀”的散列函数。

(2)确定一个解决冲突的方法,即寻求一种方法存储产生冲突的同义词。7.2.2散列函数的构造

1.数字选择法

若事先已知关键字集合,且关键字的位数比散列表的地址位数多,则可选取数字分布比较均匀的若干位作为散列地址。

例如,有一组由8位数字组成的关键字及其相应的散列地址表,如表7-2所示。

2.平方取中法

通常,要预先估计关键字的数字分布并不容易,要找出数字均匀分布的位数则更难。例如,下一组关键字(0100,0110,1010,1001,0111)就无法使用数字选择法得到较均匀的散列函数。例如,上述一组关键字的平方结果是:

(0010000,0012100,1020100,1002001,0012321)

若表长为1000,则可取中间三位作为散列地址集:

(100,121,201,020,123)

3.折叠法

若关键字位数较多,也可将关键字分割成位数相同的几段(最后一段的位数可以不同),段的长度取决于散列表的地址位数,然后将各段的叠加和(舍去进位)作为散列地址。折叠法又分移位叠加和边界叠加两种。移位叠加是将各段的最低位对齐,然后相加;边界叠加则是将两个相邻的段沿边界来回折叠,然后对齐相加。例如关键字key = 58242324169,散列表长度为1000,则将此关键字分成三位一段,两种叠加结果如下:

4.除留余数法

选择适当的正整数p,用p去除关键字,取所得余数作为散列地址,即

H(key) = key%p

(7-3)

这是一种最简单,也最常用的散列函数构造方法,它可以对关键字直接取模,也可以结合折叠法、平方取中法等运算方法。

5.基数转换法

把关键字看成是另一种进制的数后,再把它转换成原来进制的数,取其中的若干位作为散列地址。一般取大于原来基数的数作为转换的基数,并且两个基数要互为素数。例如,给定一个十进制数的关键字为(210485)10,我们把它看成以13为基数的十三进制(210485)13,再把它转换为十进制:

(210485)13=2

135+1

134+0

133+4

132+8

13+5

=(771932)10

假设散列表长度10000,则可取低四位1932作为散列地址。

6.随机数法

选择一个随机函数,取关键字的随机函数值为它的散列地址,即

H(key)=random(key)(7-4)

其中,random为随机函数。

通常,当关键字长度不相等时,采用随机数法构造散列地址较为恰当。7.2.3解决冲突的几种方法

1.开放地址法

用开放地址法解决冲突的方法是:当发生冲突时,使用某种方法在散列表中形成一个探查序列,沿着此序列逐个单元进行查找,直至找到一个空的单元时将新结点放入为止,因此在造表开始时先将表置空。那么如何形成探查序列呢?

(1)线性探查法。设表长为m,关键字个数为n。线性探查法的基本思想是:将散列表看成是一个环形表,若发生冲突的单元地址为d,则依次探查d+1,d+2,…,m-1,0,1,…,d-1,直至找到一个空单元为止。开放地址公式为

di=(d+i)%m1≤i≤m-1(7-5)

其中,d=H(key)。

例7-4

已知一组关键字集(26,36,41,38,44,15,68,12,06,51,25),用线性探查法解决冲突,试构造这组关键字的散列表。

为了减少冲突,通常令装填因子

<1,在此取

=0.75。因为n=11,所以,散列表长m= 

n/

 =15,即散列表为HT[15]。利用除留余数法构造散列函数,选p=13,即散列函数为

H(key)%13

(2)二次探查法。二次探查法的探查序列依次是:12,

-12,22,-22,…等,也就是说,发生冲突时,将同义词来回散列在第一个地址d=H(key)的两端。由此可知,发生冲突时,求下一个开放地址的公式为

(7-6)

(3)随机探查法。采用一个随机数作为地址位移计算下一个单元地址,即求下一个开放地址的公式为

di=(d+Ri)%m1≤i≤m-1(7-7)

其中,d=H(key);R1,R2,…,Rm-1是1,2,…,m-1的一个随机序列。如何得到随机序列,涉及随机数的产生问题。在实际应用中,常常用移位寄存器序列代替随机数序列。

2.拉链法

拉链法解决冲突的方法是:将所有关键字为同义词的结点链接到同一个单链表中。若选定的散列函数的值域为0~m-1,则可将散列表定义为一个由m个头指针组成的指针数组HTP[m],凡是散列地址为i的结点,均插入到以HTP[i] 为头指针的单链表之中。

例7-5

已知一组关键字和选定的散列函数和例7-4相同,用拉链法解决冲突并构造这组关键字的散列表。

因为散列函数H(key)=key%13的值域为0至12,所以散列表为HTP[13]。当把H(key)=i的关键字插入第i个单链表中时,既可插在链表的头上,也可以插在链表的尾上。若采用将新关键字插入链尾的方式,依次把给定的这组关键字插入表中,则得到的散列表如图7-5所示。图7-5拉链法构造散列表与开放地址法相比,拉链法的优点如下:

(1)拉链法不会产生堆积现象,平均查找长度较短。

(2)拉链法中各单链表的结点是动态申请的,它更适合于造表前无法确定表长的情况。

(3)在用拉链法构造的散列表中,删除结点的操作易于实现,只要简单地删去链表上相应的结点即可。7.2.4散列表的查找及分析

散列表的查找过程和建表过程相似。假设给定的值为k,根据建表时设定的散列函数H,计算出散列地址H(k),

若表中该地址对应的空间未被占用,则查找失败;否则将该地址中的结点与给定值k比较。若它们相等则查找成功;否则按建表时设定的处理冲突方法找下一个地址,如此反复下去,直到某个地址空间未被占用(查找失败)或者关键字比较相等(查找成功)为止。例如,在例7-4和例7-5的散列表中,在等概率的情况下查找成功的平均查找长度分别为

线性探查法(参见表7-3):

ASL=(1+5+1+2+2+1+1+1+1+2+3)/11=20/11

≈1.82(7-8)

拉链法(参见图7-5):

ASL=(1×7+2×2+3×1+4×1)/11=18/11≈1.64(7-9)

当n=11时,顺序查找和折半查找的平均查找长度分别为

ASLsq(11)=(11+1)/2=6

(7-10)

ASLbn(11)=(1×1+2×2+3×4+4×4)/11=33/11=3

(7-11)下面仍以表7-3和图7-5为例,分析在等概率的情况下,查找不成功时线性探查法和拉链法的平均查找长度。

在表7-3所示的线性探查法中,假设待查关键字k不在该表中,H(k)=0,则必须依次将HT[0]到HT[7]中的关键字和k或nil进行比较后,才发现HT[7]为空,即比较次数为8;若H(k)=1,则需比较7次才能确定查找不成功。类似地对H(k)=

2,3,…,12进行分析,可得不成功的平均查找长度为

ASKunsucc=(8+7+6+5+4+3+2+1+1+1+2+1+11)/13 

=52/13=4(7-12)在图7-5所示的拉链法中,若待查关键字k的散列地址为d=H(k),且第d个链表上具有k个结点

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论