ImageVerifierCode 换一换
格式:DOCX , 页数:38 ,大小:101.79KB ,
资源ID:10582010      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/10582010.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(数据结构第7章.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

数据结构第7章.docx

1、数据结构第7章第7章搜索一、复习要点本章讨论了搜索方法和简单的性能分析方法,包括适用于静态搜索表的顺序搜索和折半搜索及代表动态搜索表的二叉搜索树和AVL树。可以使用扩充的二叉搜索树描述顺序搜索和折半搜索,从而推导出估算搜索效率的公式。静态搜索表在整个程序的运行期间结构不会变化,其搜索效率随着表中对象的个数n不断增长。动态搜索表因各个对象的输入顺序不同,得到的搜索表的形态不同,典型的是二叉搜索树。在具有n个对象的二叉搜索树中,搜索效率最高的是高度最低的二叉搜索树。为确保二叉搜索树始终保持搜索效率最高,必须在输入新的对象时判断二叉搜索树是否“失去平衡”,并进行适当的平衡旋转,使二叉搜索树的高度降到

2、最低。这就是AVL树。在AVL树的讨论中,4种平衡旋转,选择参加平衡旋转的3个结点是关键,必须加以注意。本章复习的要点是:1、基本知识点理解理解搜索的概念,理解静态搜索表结构,掌握静态搜索表的顺序搜索和折半搜索算法及其性能分析方法。掌握二叉搜索树的表示、搜索、插入、删除算法及其性能分析方法,掌握AVL树的构造、插入、删除时的调整方法及其性能分析,重点是AVL树的定义、平衡化旋转、AVL树的插入和删除、AVL树的高度。2、算法设计 用有序链表表示集合时的求集合的并、交、差的算法 并查集中的构造函数、求根及合并算法 并查集中根据树的高度和根据树中结点个数进行合并的算法 设置监视哨的顺序搜索算法和不

3、设监视哨的顺序搜索算法 有序顺序表的顺序搜索算法 有序顺序表的折半搜索的递归算法和非递归算法 二叉搜索树的搜索、插入和删除算法 计算AVL树中指定结点高度的递归算法及利用此算法计算结点平衡因子的算法二、难点和重点 3、基本搜索方法 对一般表的顺序搜索算法(包括有监视哨和没有监视哨) 对有序顺序表的顺序搜索算法,包括递归和非递归算法 用判定树(即扩充二叉搜索树)描述有序顺序表的顺序搜索,以及平均搜索长度(成功与不成功)的计算。 对有序顺序表的折半搜索算法、包括递归和非递归算法 用判定树(即扩充二叉搜索树)描述有序顺序表的折半搜索,以及平均搜索长度(成功与不成功)的计算。 4、二叉搜索树 动态搜索

4、树与静态搜索树的特性 二叉搜索树的定义、二叉搜索树上的递归和非递归搜索算法 二叉搜索树搜索时的平均搜索长度(成功与不成功)的计算 二叉搜索树的插入与删除算法 AVL树结点上的平衡因子、AVL树的平衡旋转方法 高度为h的AVL树上的最少结点个数与最多结点个数 AVL树的搜索方法、插入与删除方法(不要求算法)三、教材中习题的解析7-8 设有序顺序表中的元素依次为017, 094, 154, 170, 275, 503, 509, 512, 553, 612, 677, 765, 897, 908。试画出对其进行折半搜索时的二叉搜索树, 并计算搜索成功的平均搜索长度和搜索不成功的平均搜索长度。【解答

5、】9087-9 若对有n个元素的有序顺序表和无序顺序表进行顺序搜索, 试就下列三种情况分别讨论两者在等搜索概率时的平均搜索长度是否相同?(1) 搜索失败;(2) 搜索成功, 且表中只有一个关键码等于给定值k的对象;(3) 搜索成功, 且表中有若干个关键码等于给定值k的对象, 要求一次搜索找出所有对象。【解答】(1) 不同。因为有序顺序表搜索到其关键码比要查找值大的对象时就停止搜索,报告失败信息,不必搜索到表尾;而无序顺序表必须搜索到表尾才能断定搜索失败。(2) 相同。搜索到表中对象的关键码等于给定值时就停止搜索,报告成功信息。(3) 不同。有序顺序表中关键码相等的对象相继排列在一起,只要搜索到

6、第一个就可以连续搜索到其它关键码相同的对象。而无序顺序表必须搜索全部表中对象才能确定相同关键码的对象都找了出来,所需时间就不相同了。前两问可做定量分析。第三问推导出的公式比较复杂,不再进一步讨论。7-10 假定用一个循环链表来实现一个有序表,并让指针head指向具有最小关键码的结点。指针current初始时等于head,每次搜索后指向当前检索的结点,但如果搜索不成功则current重置为head。试编写一个函数search(head, current, key)实现这种搜索。当搜索成功时函数返回被检索的结点地址,若搜索不成功则函数返回空指针0。请说明如何保持指针current以减少搜索时的平均

7、搜索长度。【解答】current605040302010head 相应的搜索函数可以定义为链表及链表结点类的友元函数,直接使用链表及链表结点类的私有数据成员。 template ListNode * Search ( ListNode * head, ListNode *& current, Type key ) ListNode * p, * q; if ( key data link; /循链搜索其值等于key的结点 if ( p-data = key ) current = p; return p; /找到, 返回结点地址 else current = head; return NULL

8、; /未找到, 返回空指针 7-11 考虑用双向链表来实现一个有序表,使得能在这个表中进行正向和反向搜索。若指针p总是指向最后成功搜索到的结点,搜索可以从p指示的结点出发沿任一方向进行。试根据这种情况编写一个函数search(head, p, key),检索具有关键码key的结点,并相应地修改p。最后请给出搜索成功和搜索不成功时的平均搜索长度。p【解答】40706050302010head template DblListNode * Search ( DblListNode * head, DblListNode *& p, Type key ) /在以head为表头的双向有序链表中搜索具有

9、值key的结点。算法可视为双向链表类和双向链表/结点类的友元函数。若给定值key大于结点p中的数据, 从p向右正向搜索, 否则, 从p向左反/向搜索。 DblListNode * q = p; if ( key data ) while ( q != NULL & q-data key ) q = q- lLink; /反向搜索 else while ( q != NULL & q-data rLink; /正向搜索 if ( q != NULL & q-data = key ) p = q; return p; /搜索成功 else return NULL; 如果指针p处于第i个结点(i =

10、 1, 2, , n),它左边有i-1个结点,右边有n-i个结点。找到左边第i-1号结点比较2次,找到第i-2号结点比较3次,找到第1号结点比较i次,一般地,找到左边第k个结点比较i-k+1次(k = 1, 2, , i-1)。找到右边第i+1号结点比较2次,找到第i+2号结点比较3次,找到第n号结点比较n-i+1次,一般地,找到右边第k个结点比较k-i+1次(k = i+1, i+2, , n)。因此,当指针处于第i个结点时的搜索成功的平均数据比较次数为 一般地,搜索成功的平均数据比较次数为 如果指针p处于第i个结点(i = 1, 2, , n),它左边有i个不成功的位置,右边有n-i+1个

11、不成功的位置。 一般地,搜索不成功的平均数据比较次数为7-12 在一棵表示有序集S的二叉搜索树中,任意一条从根到叶结点的路径将S分为3部分:在该路径左边结点中的元素组成的集合S1;在该路径上的结点中的元素组成的集合S2;在该路径右边结点中的元素组成的集合S3。S = S1 S2 S3。若对于任意的a S1, b S2, c S3, 是否总有a b c?为什么?【解答】答案是否定的。举个反例:看下图粗线所示的路径153550657045 403025 S1 = 15 , S2 = 25, 30, 35, 45 , S3 = 40, 50, 65, 70 c = 40 S3,b = 45 S2,b

12、 c 不成立。7-13 请给出下列操作序列运算的结果:Union(1, 2), Union(3, 4), Union(3, 5), Union(1, 7), Union(3, 6), Union(8, 9), Union(1, 8), Union(3, 10), Union(3, 11), Union(3, 12), Union(3, 13), Union(14, 15), Union(16, 17), Union(14, 16), Union(1, 3), Union(1, 14),要求(1) 以任意方式执行Union;(2) 根据树的高度执行Union; (3) 根据树中结点个数执行Uni

13、on。【解答】(1) 对于union(i, j),以i作为j的双亲 1215310987016141311126547(2) 按i和j为根的树的高度实现union(i, j),高度大者为高度小者的双亲; 81214310654916151311120(3) 按i和j为根的树的结点个数实现union(i, j),结点个数大者为结点个数小者的双亲。1401615187293456101113127-14 有n个结点的二叉搜索树具有多少种不同形态?【解答】 7-15 设有一个输入数据的序列是 46, 25, 78, 62, 12, 37, 70, 29 , 试画出从空树起,逐个输入各个数据而生成的二

14、叉搜索树。【解答】464646464646782525782578257825加25加46空树加78371262126262加37加12加62464678257825126237126237加29加702970707-16 设有一个标识符序列else, public, return, template,p1=0.05, p2=0.2, p3=0.1, p4=0.05, q0=0.2, q1=0.1, q2=0.2, q3=0.05, q4=0.05,计算Wij、Cij和Rij,构造最优二叉搜索树。【解答】 将标识符序列简化为 e, p, r, t ,并将各个搜索概率值化整,有eprtp1 =

15、1p2 = 4p3 = 2p4 = 1q0 = 4q1 = 2q2 = 4q3 = 1q4 = 1 (1) 首先构造只有一个内结点的最优二叉搜索树:p1p2p4p3q4q3q3q2q2q0q1q1 三个矩阵的内容如下:0123401234012340471518200072232390012221210131510102027102222479207122033313303304414040 Wij Cij Rij (2) 构造具有两个内结点的最优二叉搜索树C24 = 12T24 = 2C13 = 20T13 = 2C02 = 22T02 = 2p3p2p2 q2p4p3p1q2q1q4q3q

16、3q2q1q0(3) 构造具有三个内结点的最优二叉搜索树C03 = 32T03 = 2C14 = 27T14 = 2p2p2p1p3q1p3p4q2q3q2q1q0q4q3(4) 构造具有四个内结点的最优二叉搜索树 C04 = 39T04 = 2p2左子树 T01, 其 C01 = 7右子树 T24, 其 C24 = 12p1p3q2q1q0p4q4q37-17 在二叉搜索树上删除一个有两个子女的结点时,可以采用以下三种方法:(1) 用左子树TL上具有最大关键码的结点X顶替,再递归地删除X。 (2) 交替地用左子树TL上具有最大关键码的结点和右子树TR上具有最小关键码的结点顶替,再递归地删除适

17、当的结点。(3) 用左子树TL上具有最大关键码的结点或者用右子树TR上具有最小关键码的结点顶替,再递归地删除适当的结点。可随机选择其中一个方案。试编写程序实现这三个删除方法,并用实例说明哪一个方法最易于达到平衡化。【解答】1 在被删结点有两个子女时用左子树TL中具最大关键码的结点顶替的算法:template BstNode * BST : leftReplace ( BstNode * ptr ) BstNode * temp = ptr-leftChild; /进到ptr的左子树 while ( temp-rightChild != NULL ) temp = temp-rightChild

18、; /搜寻中序下最后一个结点 ptr-data = temp-data; /用该结点数据代替根结点数据 return temp; 在被删结点有两个子女时用右子树TR中具最小关键码的结点顶替的算法: template BstNode * BST : rightReplace ( BstNode * ptr ) BstNode * temp = ptr-rightChild; /进到ptr的右子树 while ( temp-leftChild != NULL ) temp = temp-leftChild; /搜寻中序下最后一个结点 ptr-data = temp-data; /用该结点数据代替根

19、结点数据 return temp; (1) 用左子树TL上具有最大关键码的结点X顶替,再递归地删除X。template void BST : Remove ( Type& x, BstNode *& ptr ) /私有函数:在以ptr为根的二叉搜索树中删除含x的结点。若删除成功则新根通过ptr返回。 BstNode * temp; if ( ptr != NULL ) if ( x data ) Remove ( x, ptr-leftChild ); /在左子树中执行删除 else if ( x ptr-data ) Remove ( x, ptr-rightChild ); /在右子树中执

20、行删除 else if ( ptr-leftChild != NULL & ptr-rightChild != NULL ) / ptr指示关键码为x的结点,它有两个子女 temp = leftReplace ( ptr ); /在ptr的左子树中搜寻中序下最后一个结点顶替x Remove ( ptr-data, ptr-rightChild ); /在ptr的右子树中删除该结点 else / ptr指示关键码为x的结点,它只有一个或零个子女 temp = ptr; if ( ptr-leftChild = NULL ) ptr = ptr-rightChild; /只有右子女 else if

21、 ( ptr-rightChild = NULL ) ptr = ptr-leftChild; /只有左子女 delete temp; (2) 交替地用左子树TL上具有最大关键码的结点和右子树TR上具有最小关键码的结点顶替,再递归地删除适当的结点。template void BST : Remove ( Type& x, BstNode *& ptr, int& dir ) /私有函数:在以ptr为根的二叉搜索树中删除含x的结点。若删除成功则新根通过ptr返回。在/参数表中有一个引用变量dir, 作为调整方向的标记。若dir = 0, 用左子树上具有最大关键码的/结点顶替被删关键码; 若dir

22、 = 1, 用右子树上具有最小关键码的结点顶替被删关键码结点, 在调/用它的程序中设定它的初始值为0。 BstNode * temp; if ( ptr != NULL ) if ( x data ) Remove ( x, ptr-leftChild, dir ); /在左子树中执行删除 else if ( x ptr-data ) Remove ( x, ptr-rightChild, dir ); /在右子树中执行删除 else if ( ptr-leftChild != NULL & ptr-rightChild != NULL ) / ptr指示关键码为x的结点,它有两个子女 if

23、( dir = 0 ) temp = leftReplace ( ptr ); dir = 1; /在ptr的左子树中搜寻中序下最后一个结点顶替x Remove ( ptr-data, ptr-rightChild, dir ); /在ptr的右子树中删除该结点 else temp = rightReplace ( ptr ); dir = 0; /在ptr的右子树中搜寻中序下第一个结点顶替x Remove ( ptr-data, ptr-leftChild, dir ); /在ptr的左子树中删除该结点 else / ptr指示关键码为x的结点,它只有一个或零个子女 temp = ptr;

24、if ( ptr-leftChild = NULL ) ptr = ptr-rightChild; /只有右子女 else if ( ptr-rightChild = NULL ) ptr = ptr-leftChild; /只有左子女 delete temp; (3) 用左子树TL上具有最大关键码的结点或者用右子树TR上具有最小关键码的结点顶替,再递归地删除适当的结点。可随机选择其中一个方案。#include template void BST : Remove ( Type& x, BstNode *& ptr ) /私有函数:在以ptr为根的二叉搜索树中删除含x的结点。若删除成功则新根通

25、过ptr返回。在/程序中用到一个随机数发生器rand( ), 产生032767之间的随机数, 将它除以16384, 得到02/之间的浮点数。若其大于1, 用左子树上具有最大关键码的结点顶替被删关键码; 若其小于或等/于1, 用右子树上具有最小关键码的结点顶替被删关键码结点, 在调用它的程序中设定它的初始/值为0。 BstNode * temp; if ( ptr != NULL ) if ( x data ) Remove ( x, ptr-leftChild ); /在左子树中执行删除 else if ( x ptr-data ) Remove ( x, ptr-rightChild );

26、/在右子树中执行删除 else if ( ptr-leftChild != NULL & ptr-rightChild != NULL ) / ptr指示关键码为x的结点,它有两个子女 if ( (float) ( rand ( ) / 16384 ) 1 ) temp = leftReplace ( ptr ); /在ptr的左子树中搜寻中序下最后一个结点顶替x Remove ( ptr-data, ptr-rightChild ); /在ptr的右子树中删除该结点 else temp = rightReplace ( ptr ); /在ptr的右子树中搜寻中序下第一个结点顶替x Remove ( ptr-data, ptr-leftChild ); /在ptr的左子树中删除该结点 else / ptr指示关键码为x的结点,它只有一个或零

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1