数据结构第九章(查找)习题参考答案作者名:不详 来源:网友提供 06年6月8日
一、基础知识题 1.对含有n个互不相同元素的集合,同时找最大元和最小元至少需进行多少次比较? 答:我们可以设立两个变量max和min用于存放最大元和最小元(的位置),第一次取两个元素进行比较,大的放入max,小的放入min,从第2次开始,每次取一个元素先和max比较,如果大于max则以它替换max,并结束本次比较;若小于max则再与min相比较,在最好的情况下,一路比较下去都不用和min相比较,所以这种情况下,至少要进行n-1次比较就能找到最大元和最小元。(顺便说一下,最坏情况下,要进行2n-3次比较才能得到结果)2.若对具有n个元素的有序的顺序表和无序的顺序表分别进行顺序查找,试在下述两种情况下分别讨论两者在等概率时的平均查找长度:(1)查找不成功,即表中无关键字等于给定值K的记录;(2)查找成功,即表中有关键字等于给定值K的记录。
3.画出对长度为18的有序的顺序表进行二分查找的判定树,并指出在等概率时查找成功的平均查找长度,以及查找失败时所需的最多的关键字比较次数。 查找失败时,最多的关键字比较次树不超过判定树的深度,此处为5.如图: 4.为什么有序的单链表不能进行折半查找?
5.设有序表为(a,b,c,e,f,g,i,j,k,p,q),请分别画出对给定值b,g和n进行折半查找的过程。
经过三次比较,查找成功。 g的查找过程如下: n的查找过程如下: 经过四次比较,查找失败。 6.将(for, case, while, class, protected, virtual, public, private, do, template, const ,if, int)中的关键字依次插入初态为空的二叉排序树中,请画出所得到的树T。然后画出删去for之后的二叉排序树T',若再将for 插入T'中得到的二叉排序树T''是否与T相同?最后给出T"的先序、中序和后序序列。 答:见题图: T"的中序序列是:case class const do for if int private protected public template virtual while T"的后序序列是:const class case for int if private template public virtual protected while do 二叉排序树T如下图:
删去for后的二叉排序树如下图:圈内的for表示再插入后的结点:
7.对给定的关键字集合,以不同的次序插入初始为空的树中,是否有可能得到同一棵二叉排序树? 8.将二叉排序树T的先序序列中的关键字依次插入一空树中,所得和二叉排序树T'与T"是否相同?为什么? 答:这两棵二叉树完全相同。9.设二叉排序树中关键字由1至1000的整数构成,现要查找关键字为363的结点,下述关键字序列哪一个不可能是在二叉排序树上查找到的序列? (a) 2,252,401,398,330, 344,397,363; (b) 924, 220, 911, 244, 898, 258, 362, 363; (c) 925, 202, 911, 240, 912, 245, 363; (d) 2, 399, 387, 219, 266, 382, 381, 278, 363. 10.设二叉排序树中关键字互不相同,则其中最小元必无左孩子,最大元必无右孩子。此命题是否正确?最小元和最大元一定是叶子吗?一个新结点总是插在二叉排序树的某叶子上吗?
但最大元和最小元不一定是叶子,它也可以是根、内部结点(分支结点)等,这得根据插入结点时的次序而定。如3,1,2,4 这个集合,根据不同的插入次序可以得到不同的二叉排序树: ○3 ○4
11.在一棵m阶的B-树中,当将一关键字插入某结点而引起该结点的分裂时,此结点原有多少个关键字?若删去某结点中的一个关键字,而导致结点合并时,该结点中原有几个关键字? 12.在一棵B-树中,空指针数总是比关键字数多一个,此说法是否正确?请问包含8个关键字的3阶B-树(即2-3树)最多有几个结点?最少有几个结点?画出这两种情况的B-树。
见题图。:图如下: 15. 在含有n个关键字的m阶B-树中进行查找,至多读盘多少次?完全平衡的二叉排序树的读盘次数大约比它大多少倍? 16.为什么在内存中使用的B-树通常是3阶的,而不使用更高阶的B-树? 17.为什么二叉排序树长高时,新结点总是一个叶子,而B-树长高时,新结点总是根?哪一种长高能保证树平衡? 答:因为在二叉排序树中,关键字总是作为一个叶子结点插入以原来的树中,所以当树增高时,新结点总是一个叶子;而B-树中关键字插入总是插入到叶子结点内部,在叶结点中的关键字数目尚未超过它能够容纳的数目之前是不会增加结点的,当关键字数超过结点可容纳的数目时,叶结点就会发生分裂,产生一个新结点(但不一定引起树增高),并且将其中的中间结点传至上一层,只有当这种分裂操作传递至根结点并引起根结点的分裂时,才能引起树高增加,此时产生一个新的根结点。所以说B树长高时,新结点总是根。 显然,后一种长高总能保证树的平衡。 18.已知关键字序列为(PAL,LAP,PAM,MAP,PAT,PET,SET,SAT,TAT,BAT)试为它们设计一个散列函数,将其映射到区间[0..n-1]上,要求碰撞尽可能的少。这里n=11,13,17,19.
int Hash (char key[]) 我们可以设计一个程序来看看用这个散列函数得到的所有关键字映射到区间的位置: #include <stdio.h> void main() char s[10][4]={"PAL","LAP","PAM","MAP","PAT","PET","SET","SAT","TAT","BAT"}; 19.对于一组给定的、固定不变的关键字序列,有可能设计出无冲突的散列函数H,此时称H为完备的散列函数(perfect hashing function),若H能无冲突地将关键字完全填满散列表,则称H是最小完备(minimal perfect)的散列函数。通常找完备的散列函数非常困难,找最小完备的散列函数就更困难。请问: (1)若h是已知关键字集合K的完备的散列函数,若要增加一个新的关键字到集合K,一般情况下H还是完备的吗? (2)已知关键字集合为(81,129,301,38,434,216,412,487,234),散列函数为H(x)=(x+18)/63,请问H是完备的吗?它是最小完备的吗? (3)考虑由字符串构成的关键字集合(Bret,Jane,Shirley,Bryce,Michelle,Heather),试为散列表[0..6]设计一个完备的散列函数。(提示:考虑每个字符串的第3个字符,即s[2]) 答:(1) 一般情况下H不是完备的,如果说插入一个新的关键字它还是完备的,那么再插入一个呢?它岂不是永远是完备的散列函数了? 所以一般情况下它不能总是完备的,只有一些很少的情况下它还可能是完备的。 (2)这个H是完备的,其函数值依次为:1,2,5,0,7,3,6,8,4。如果散列表长m=9时,它就是最小完备的。 (3) 这个函数如下:
20.设散列函数为h(key)=key%101,解决冲突的方法为线性探查,表中用"-1"表示空单元。若删去散列表HT中的304(即令HT[1]=-1)之后,在表HT中查找707将会发生什么?若将删去的表项标记为"-2",查找时探查到-2继续向前搜索,探查到-1时终止搜索。请问用这种方法删304后能否正确地查找到707? 0 1 2 3 100 如果改用"-2"作为删除标记,则可以正确找到707所在的结点。 21.设散列表长度为11,散列函数h(x)=x%11,给定的关键字序列为:1,13,13,34,38,33,27,22.试画出分别用拉链法和线性探查法解决冲突时所构造的散列表,并求出在等概率情况下,这两咱方法查找成功和失败时的平均查找长度。请问装填因子的值是什么? 答:拉链法如下图:(后面的框框就不画了) T[0..10] 线性探查法如下图:
ASLscuu=(1*4+2*3+3*1)/8=1.625 查找失败时平均查找长度为: ASLunsucc=(2+3+1+0+0+0+2+0+0+0+0)/11=0.73 用线性探查法查找成功时平均查找长度为: ASLsucc=(1+1+1+3+4+1+7+8)/8=3.25 查找失败时平均查找长度为: ASLunsucc=(9+8+7+6+5+4+3+2+1+1+1)/11=4.3 装填因子α拉链=4/11=0.36 α线性探查=8/11=0.73
22.假定有k个关键字互为同义词,若用线性探查法把这些同义词存入散列表中,至少要进行多少次探查?
也就是说,在散列表的一连串连续空间内,第一个关键字只需探查一次,第二个就要探查2次,如此这般,第k个关键字就要探查k次才能找到位置存放。所以至少要把它们全加起来才够。
23.为什么说当装填因子非常接近1时,线性探查类似于顺序查找?为什么说当装填因子比较小(比如α=0.7左右)时,散列查找的平均查找时间为O(1)?
|
||
| |