下载
下载
第7章 跳表和散列
对于一个有n 个元素的有序数组,用折半搜索法进行搜索所需要的时间为 O ( l o gn) ,而对一
个有序链表进行搜索所需要的时间为 O (n) 。我们可以通过对有序链表上的全部或部分节点增加
额外的指针,来提高搜索性能。在搜索时,可以通过这些指针来跳过链表中若干个节点,因此
没有必要从左到右搜索链表中的所有节点。
增加了向前指针的链表叫作跳表。跳表不仅能提高搜索性能,同时也可以提高插入和删除
操作的性能。它采用随机技术决定链表中哪些节点应增加向前指针以及在该节点中应增加多少
个指针。采用这种随机技术,跳表中的搜索、插入、删除操作的时间均为 O ( l o gn) ,然而,最
坏情况下时间复杂性却变成 (n) 。相比之下,在一个有序数组或链表中进行插入 /删除操作的
时间为O( n) ,最坏情况下为 (n) 。
散列法是用来搜索、插入、删除记录的另一种随机方法。与跳表相比,它的插入 /删除操
作时间提高到 ( 1 ) ,但最坏情况下仍为 (n) 。尽管如此,在经常将所有元素按序输出或按序
号搜索元素时(如寻找第1 0个最小元素) ,跳表的执行效率将优于散列。
本章所给出的应用是关于文本压缩和解压缩的应用,该应用用散列实现。所设计的程序基
于当前流行的L i v _ Z e m p e l _ We l c h算法(简称L Z W算法)。
7.1 字典
字典(d i c t i o n a r y )是一些元素的集合。每个元素有一个称作key 的域,不同元素的key 各
不相同。有关字典的操作有:
• 插入具有给定关键字值的元素。
• 在字典中寻找具有给定关键字值的元素。
• 删除具有给定关键字值的元素。
抽象数据类型D i c t i o n a ry 的描述见ADT 7-1 。若仅按照一个字典元素本身的关键字来访问该
元素,则称为随机访问(random access )。而顺序访问(sequential access )是指按照关键字的
递增顺序逐个访问字典中的元素。顺序访问需借助于 Begin (用来返回关键字最小的元素 )和
Next (用来返回下一个元素)等操作来实现。对于本章中所实现的部分字典,既可以采用随机访
问方式,也可以采用顺序访问方式。
ADT7-1 字典的抽象数据类型描述
抽象数据类型D i c t i o n a ry {
实例
具有不同关键字的元素集合
操作
C re a t e( ) :创建一个空字典
S e a rc h(k, x ) :搜索关键字为k 的元素,结果放入x ;
如果没找到,则返回f a l s e ,否则返回t r u e
I n s e rt (x) :向字典中插入元素x
第 7章 跳表和散列 2 1 9
下载
Delete (k, x) :删除关键字为k 的元素,并将其放入x
}
有重复元素的字典(dictionary with duplicates )与上面定义的字典相似,只是它允许多个
元素有相同的关键字。在有重复元素的字典中,在进行搜索和删除时需要一个规则来消除岐义。
也就是说,如果要搜索(或删除)关键字为k 的元素,那么在所有关键字为k 值的元素中应该返回
(或删除)哪一个呢? 在有些字典应用中,可能需要:删除在某个时间以后插入的所有元素。
例7-1 一个班中注册学习数据结构课程的学生构成了一个字典。当有一个新学生注册时,就
要在字典中插入与该学生相关的元素 (记录) 。当有人要放弃这门课程时,则删除他的记录。在
上课过程中,老师可以查询字典以得到与某特定学生相关的记录或修改记录 (例如,加入或修
改考试成绩) 。学生的姓名域可作为关键字。
例7-2 在编译器中定义用户描述符的符号表( symbol tab