欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    中南大学数据结构与算法第9章查找课后作业答案(20页).doc

    • 资源ID:35069070       资源大小:90KB        全文页数:20页
    • 资源格式: DOC        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    中南大学数据结构与算法第9章查找课后作业答案(20页).doc

    -第9章查找习题练习答案1.对含有n个互不相同元素的集合,同时找最大元和最小元至少需进行多少次比较? 答:设变量max和min用于存放最大元和最小元(的位置),第一次取两个元素进行比较,大的放入max,小的放入min。从第2次开始,每次取一个元素先和max比较,如果大于max则以它替换max,并结束本次比较;若小于max则再与min相比较,在最好的情况下,一路比较下去都不用和min相比较,所以这种情况下,至少要进行n-1次比较就能找到最大元和最小元。2.若对具有n个元素的有序的顺序表和无序的顺序表分别进行顺序查找,试在下述两种情况下分别讨论两者在等概率时的平均查找长度:(1)查找不成功,即表中无关键字等于给定值K的记录;(2)查找成功,即表中有关键字等于给定值K的记录。答:查找不成功时,需进行n+1次比较才能确定查找失败。因此平均查找长度为n+1,这时有序表和无序表是一样的。查找成功时,平均查找长度为(n+1)/2,有序表和无序表也是一样的。因为顺序查找与表的初始序列状态无关。3.画出对长度为18的有序的顺序表进行二分查找的判定树,并指出在等概率时查找成功的平均查找长度,以及查找失败时所需的最多的关键字比较次数。答: 等概率情况下,查找成功的平均查找长度为:ASL=(1+2*2+3*4+4*8+5*3)/18=3.556 查找失败时,最多的关键字比较次树不超过判定树的深度,此处为5.4.为什么有序的单链表不能进行折半查找?答:因为链表无法进行随机访问,如果要访问链表的中间结点,就必须先从头结点开始进行依次访问,这就要浪费很多时间,还不如进行顺序查找,而且,用链存储结构将无法判定二分的过程是否结束,因此无法用链表实现二分查找。5.设有序表为(a,b,c,e,f,g,i,j,k,p,q),请分别画出对给定值b,g和n进行折半查找的过程。 解: (1)查找b的过程如下(其中方括号表示当前查找区间,圆括号表示当前比较的关键字)下标:  1  2  3  4  5  6   7   8  9 10 11 12 13 第一次比较: a  b  c  d  e  f  (g)  h  i  j  k  p  q第二次比较: a  b (c) d  e  f  g   h  i  j  k  p  q第三次比较: a (b)c  d  e  f   g   h  i  j  k  p  q经过三次比较,查找成功。  (2)g的查找过程如下:    a b c d e f (g) h i j k p q    一次比较成功。  (3)n的查找过程如下:        下标:  1  2  3  4  5  6  7   8  9 10 11 12  13     第一次比较: a  b  c  d  e  f (g)  h  i  j  k  p  q  第二次比较:  a  b  c  d  e  f  g  h  i (j) k  p  q  第三次比较:  a  b  c  d  e  f  g   h  i  j k (p) q  第四次比较:  a  b  c  d  e  f  g   h  i  j k p  q  经过四次比较,查找失败。6.将(for, case, while, class, protected, virtual, public, private, do, template, const ,if, int)中的关键字依次插入初态为空的二叉排序树中,请画出所得到的树T。然后画出删去for之后的二叉排序树T',若再将for 插入T'中得到的二叉排序树T''是否与T相同?最后给出T"的先序、中序和后序序列。答:二叉排序树T如下图: 删去for后的二叉排序树如下图:再插入结点for后的二叉排序树T":    二叉排序树T"与T不同    T"的先序序列是:do case class const while protected private if for int virtual public template T"的中序序列是:case class const do for if int private protected public template virtual whileT"的后序序列是:const class case for int if private template public virtual protected while do7.对给定的关键字集合,以不同的次序插入初始为空的树中,是否有可能得到同一棵二叉排序树?答:    有可能。如有两个序列:3,1,2,4 和 3,4,1,2,它们插入空树所得的二叉排序树是相同的。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.答:(c)是不可能查找到的序列。把这四个序列各插入到一个初始为空的二叉排序树中,结果可以发现,(c)序列所形成的不是一条路径,而是有分支的,可见它是不可能在查找过程中访问到的序列。10.设二叉排序树中关键字互不相同,则其中最小元必无左孩子,最大元必无右孩子。此命题是否正确?最小元和最大元一定是叶子吗?一个新结点总是插在二叉排序树的某叶子上吗? 答:此命题正确。假设最小元有左孩子,则根据二叉排序树性质,此左孩子应比最小元更小,如此一来就产生矛盾了,因此最小元不可能有左孩子,对于最大元也是这个道理。 但最大元和最小元不一定是叶子,它也可以是根、内部结点(分支结点)等,这得根据插入结点时的次序而定。新结点总是作为叶子插入在二叉排序树中的。11.在一棵m阶的B-树中,当将一关键字插入某结点而引起该结点的分裂时,此结点原有多少个关键字?若删去某结点中的一个关键字,而导致结点合并时,该结点中原有几个关键字?答:在一棵m阶的B-树中,若由于一关键字的插入某结点而引起该结点的分裂时,则该结点原有m-1个关键字。若删去某结点中一个关键字而导致结点合并时,该结点中原有m/2-1个关键字。12.在一棵B-树中,空指针数总是比关键字数多一个,此说法是否正确?请问包含8个关键字的3阶B-树(即2-3树)最多有几个结点?最少有几个结点?画出这两种情况的B-树。 答:这个说法是正确的。包含8个关键字的3阶B-树最多有7个结点,最少有4个结点。13.从空树开始,依次输入20,30,50,52,60,68,70,画出建立2-3树的过程。并画出删除50和68后的B-树状态。 答:过程如下:(1) 插入20,30: (2) 插入50:(3) 插入52:(4) 插入60:(5) 插入68:(6) 插入70:(7)删去50:(8) 删去6814.画出依次插入z,v,o,p,w,y到图9.12(h)所示的5阶B-树的过程。   解: (1)插入z后:(2)插入v,o后 (3)插入 p,w,y后 16.为什么在内存中使用的B-树通常是3阶的,而不使用更高阶的B-树? 答:    因为查找等操作的cpu时间在B-树上是O(lgn·(m/lgt),而m/lgt>1,所以m较大时它所费时间比平衡的二叉排序树上相应操作时间大得多,因此,仅在内存中使用的B-树通常取最小值317.为什么二叉排序树长高时,新结点总是一个叶子,而B-树长高时,新结点总是根?哪一种长高能保证树平衡? 答:    因为在二叉排序树中,关键字总是作为一个叶子结点插入以原来的树中,所以当树增高时,新结点总是一个叶子;而B-树中关键字插入总是插入到叶子结点内部,在叶结点中的关键字数目尚未超过它能够容纳的数目之前是不会增加结点的,当关键字数超过结点可容纳的数目时,叶结点就会发生分裂,产生一个新结点(但不一定引起树增高),并且将其中的中间结点传至上一层,只有当这种分裂操作传递至根结点并引起根结点的分裂时,才能引起树高增加,此时产生一个新的根结点。所以说B树长高时,新结点总是根。    显然,后一种长高总能保证树的平衡。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个字符,即s2)答:(1) 一般情况下H不是完备的,如果说插入一个新的关键字它还是完备的,那么再插入一个呢?它岂不是永远是完备的散列函数了? 所以一般情况下它不能总是完备的,只有一些很少的情况下它还可能是完备的。(2)这个H是完备的,其函数值依次为:1,2,5,0,7,3,6,8,4。如果散列表长m=9时,它就是最小完备的。(3) 这个函数如下:int Hash (char key) return key2%7;20.设散列函数为h(key)=key%101,解决冲突的方法为线性探查,表中用"-1"表示空单元。若删去散列表HT中的304(即令HT1=-1)之后,在表HT中查找707将会发生什么?若将删去的表项标记为"-2",查找时探查到-2继续向前搜索,探查到-1时终止搜索。请问用这种方法删304后能否正确地查找到707?0 1 2 3 100 HT202 304 507 707 .      答:    查找707时,首先根据散列函数计算得出该元素应在散列表中的0单元,但是在0单元没有找到,因此将向下一单元探查,结果发现该单元是-1(为空单元),所以结束查找,这将导致707无法找到。    如果改用"-2"作为删除标记,则可以正确找到707所在的结点。21.设散列表长度为11,散列函数h(x)=x%11,给定的关键字序列为:1,13,13,34,38,33,27,22.试画出分别用拉链法和线性探查法解决冲突时所构造的散列表,并求出在等概率情况下,这两种方法查找成功和失败时的平均查找长度。请问装填因子的值是什么? 答:(1)拉链法如下图:  T0.10       0    33 22        1    1 12 34        2    13        3        4        5    38 27 6        7        8        9        10       (2)线性探查法如下图:      下标   0   1   2   3   4   5   6   7   8   9  10             T0.10331 131234382722                  探查次数   1   1   1   3   4   1   7   8  用拉链法的查找成功平均查找长度为:    ASLsucc=(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.7322.假定有k个关键字互为同义词,若用线性探查法把这些同义词存入散列表中,至少要进行多少次探查?答:    至少要进行1+2+3.+k-1+k次探查。    也就是说,在散列表的一连串连续空间内,第一个关键字只需探查一次,第二个就要探查2次,如此这般,第k个关键字就要探查k次才能找到位置存放。所以至少要把它们全加起来才够。23.为什么说当装填因子非常接近1时,线性探查类似于顺序查找?为什么说当装填因子比较小(比如=0.7左右)时,散列查找的平均查找时间为O(1)?答:    当非常接近1时,整个散列表几乎被装满。由于线性探查法在关键字同义时解决冲突的办法是线性地向后查找,当整个表几乎装满时,它就很类似于顺序查找了。    当比较小时,关键字碰撞的几率比较小,一般情况下只要按照散列函数计算出的结果能够1次性就找到相应结点,因此它的平均查找时间接近于1.24.设顺序表中关键字是递增有序的,试写一顺序查找算法,将哨兵设在表的高下标端。然后求出等概率情况下查找成功与失败时的ASL.答:  typedef structKeyType key;InfoType otherinfo; /此类型依赖于应用NodeType;typedef NodeType SeqListn+1; /n号单元用作哨兵int SeqSearch(Seqlist R,KeyType K) /在关键字递增有序的顺序表R0.n-1中顺序查找关键字为K的结点,/成功时返回找到的结点位置,失败时返回-1int i;Rn.key=K; /设置哨兵for(i=0;Ri.key<=K;i-); /从表前往后找if (i<n&&Ri.key=K) return i; /Ri是要找的结点else return -1  /SeqSearch等概率情况下查找成功ASL=(1+2+3+n)/n等概率情况下查找失败时的ASL=(1+2+3+n+n+1)/(n+1)25试写出二分查找的递归算法。解:  int BinSearch(SeqList R,KeyType K,int low,int high) /在有序表Rlow.high中进行二分查找,成功时返回结点的位置,失败时返回零int mid; /置当前查找区间上、下界的初值if (low<=high) /当前查找区间Rlow.high非空mid=(low+high)/2;if(Rmid.key=K) return mid; /查找成功返回if(Rmid.kdy>K)return BinSearch( R,K,low,mid-1)/在Rlow.mid-1中查找elsereturn BinSearch( R,K,mid+1,high); /在Rmid+1.high中查找return 0; /当low>high时表示查找区间为空,查找失败 /BinSeareh26试写一算法判别给定的二叉树是否为二叉排序树,设此二叉树以二叉链表为存储结构,且树中结点的关键字均不相同。解:由二叉排序树的定义可得:二叉排序树中左子树的所有结点的值都小于根结点的值,所有右子树中结点的值都大于根结点的值。那么只要对待判定的二叉树中的结点按层遍历并判断即可。在该算法中要用到队列保存已遍历的结点指针。typedef BinTNode *DataType;/循环队列中元素为二叉树结点指针 int BinSortStree(BinTree T) CirQueue Q;BinTNode *p;if (!T) return 1;/空树为二叉排序树InitQueue(&Q);EnQueue(&Q,T);while(!QueueEmpty(&Q)p=DeQueue(&Q);if (p->lchild)if (p->data<p->lchild->data) return -1;/不是二叉排序树else EnQueue(&Q,p->lchild);if (p->rchild)if (p->data>p->rchild->data) return -1;/不是二叉排序树else EnQueue(&Q,p->rchild);return 1;/是二叉排序树27.试写一递归算法,从大到小输出二叉排序树中所有其值不小于x的关键字。要求算法的时间为O(lgn+m),n为树中结点数,m为输出关键字个数(提示:先遍历右子树,后遍历左子树)。答:typedef int KeyType; /假定关键字类型为整数typedef struct node /结点类型KeyType key; /关键字项InfoType otherinfo; /其它数据域,InfoType视应用情况而定,下面不处理它struct node *lchild,*rchild; /左右孩子指针 BSTNode;typedef BSTNode *BSTree;void OUTPUTNODE(BSTree T,KeyType x)/从大到小输出二叉排序树中所有其值不小于x的关键字if (T)OUTPUTNODE( T->rchild,x);if (T->key>=x) printf("%d",T->key);OUTPUTNODE( T->Lchild,x);28.写一个遍历B-树的算法,使输出的关键字序列递增有序。算法中的读盘操作可假定为DiskRead。答:#define Max l000 /结点中关键字的最大数目:Max=m-1,m是B-树的阶#define Min 500 /非根结点中关键字的最小数目:Min=m/2(-1typedef int KeyType; /KeyType应由用户定义typedef struct node /结点定义中省略了指向关键字代表的记录的指针int keynum; /结点中当前拥有的关键字的个数,keynum<=MaxKeyType keyMax+1; /关键字向量为key1.keynum,key0不用。struct node *parent; /指向双亲结点struct node *sonMax+1;/孩子指针向量为son0.keynumBTreeNode;typedef BTreeNode *BTree;void travelBtree(BTree T)/按关键字递增序输出B-树序列int i;if (T)for(i=0;i<=T->keynum;i+)/T->keynum个关键字的结点有T->keynum+1棵子树if (T->soni)DiskRead(T->soni);/读入根结点的第i棵子树travelBtree(T->soni);/遍历第i棵子树if (i<T->keynmu)/若刚遍历的子树不是最后一棵子树printf("%d",T->keyi+1; 29若采用除余法作为散列函数,线性探查解决冲突,则9.4.4节中通用的散列表查找算法可改写为对线性探查专用的查找算法:int HashSearch(HashTable T,KeyType K,int *pos)int i=0;/记录探查次数*pos=K%m; /散列函数值作为第一个散列地址while(i+<m) /最多探查m次if(T*pos.key=K) return 1;/查找成功返回if(T*pos.key=NIL) return 0;/查找失败返回*pos=(*pos+1)%m;/用线性探查法求下一个探查地址return -1;/查找失败,且表满/HashSearch假设散列表上的删除操作已将结点的关键字标记为DELETED(例如,不妨设DELETED为-2)。请修改上述散列表上的查找算法及插入算法HashInsert,使之能正确地查找和插入。解:(1)查找算法#define DELETED -2#define NIL -1 /空结点标记依赖于关键字类型,本节假定关键字均为非负整数#define M 997 /表长度依赖于应用,但一般应根据。确定m为一素数typedef struct /散列表结点类型KeyType key;InfoType otherinfo; /此类依赖于应用NodeType;typedef NodeType HashTablem; /散列表类型int HashSearch(HashTable T,KeyType K,int *pos)int i=0;/记录探查次数*pos=K%m; /散列函数值作为第一个散列地址while(i+<m) /最多探查m次if(T*pos.key=K) return 1;/查找成功返回if(T*pos.key=NIL) return 0;/查找失败返回*pos=(*pos+1)%m;/用线性探查法求下一个探查地址return -1;/查找失败,且表满/HashSearch(2)插入算法HashInsertint HashInsert(HashTable T,KeyType K)/返回1,表示表中已有k,返回0表示正常插入,返回-1表示插入失败int i=0;/记录探查次数int j=-1;/记录DELETED的位置int pos=K%m; /散列函数值作为第一个散列地址while(i+<m) /最多探查m次if(Tpos.key=K) return 1;/查找成功返回if(Tpos.key=NIL)if (j=-1) Tpos.key=K;/查找失败,插入else Tj.key=K;/插入到被删除元素留出的位置return 0;/正常插入if(Tpos.key=DELETED)if (j=-1) j=pos; pos=(pos+1)%m;/用线性探查法求下一个探查地址return -1;/查找失败,且表满30用拉链法解决冲突,有关的类型说明和插入算法如下,请据此写出散列表的建表、查找及删除算法。  typedef struct nodeKeyType key;/关键字InfoType Otherinfo;/以下不处理此域struct node *next;/链域CNodeType;typedef CNodeType *CHashTablem;/散列表类型是一个指针数组void ChainHashInsert(CHashTable T,KeyType K)/将关键字K插入表T中,设散列函数为h(K)=K%mCNodeType *p;int addr;p=ChainHashSearch(T,K);/在T中查找有无关键字为K的结点if (p) printf("duplicate key!");/关键字已存在else /申请一个新结点,将其关键字置为K,并插入相应链表的头上addr=K%m;/求散列函数值作为散列地址p=(CNodeType *)malloc(sizeof(CNodeType);p->key=K;p->next=Taddr;Taddr=p;/将*p插入链表Taddr的头部 /endif/ChainHashInsert解:(1)建表void ChainHashCreat(CHashTable T)/设散列函数为h(K)=K%m,建立以拉链法为解决冲突方法的散列表CNodeType *p;int addr;int i;KeyType K;for(i=0;i<m;i+)/置空的散列表Ti=NULL;scanf("%d",&K);while (K)/设输入的数据以0结束p=ChainHashSearch(T,K);/在T中查找有无关键字为K的结点if (p) printf("duplicate key!");/关键字已存在else /申请一个新结点,将其关键字置为K,并插入相应链表的头上addr=K%m;/求散列函数值作为散列地址p=(CNodeType *)malloc(sizeof(CNodeType);p->key=K;p->next=Taddr;Taddr=p;/将*p插入链表Taddr的头部 /endifscanf("%d",&K);/endwhile/ChainHashCreat(2)查找CNodeType ChainHashSearch(CHashTable T,KeyType K)/查找关键字值为K的结点,若有返回该结点指针,否则返回NULLCNodeType *p;int addr;addr=K%m;/求散列函数值p=Taddr;while (p)&&(p->key!=K)p=p->next;return p;(3)删除CNodeType ChainHashDelete(CHashTable T,KeyType K)/删除关键字值为K的结点,若有返回该结点指针,否则返回NULL          CNodeType *p,*q;int addr;addr=K%m;/求散列函数值p=Taddr;if (p)&&(p->key=K) Taddr=p->next;/要删的是 Taddr表的第一个结点while (p->next)&&(p->next->key!=K)p=p->next;if (p->next)q=p;p=p->next;q->next=p->next;/删除preturn p;-第 20 页-

    注意事项

    本文(中南大学数据结构与算法第9章查找课后作业答案(20页).doc)为本站会员(1595****071)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开