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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

本文(静态数据表类定义.doc)为本站会员(dcjskn)主动上传,道客多多仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知道客多多(发送邮件至docduoduo@163.com或直接QQ联系客服),我们立即给予删除!

静态数据表类定义.doc

1、第 9 章 排序1静态数据表类定义#include const int DefaultSize = 100;template class dataList /数据表的前视声明 template class Element /数据表元素类的定义friend class dataList ;private:Type key; /排序码field otherdata; /其它数据成员public:Type getKey ( ) return key; /取当前结点的排序码void setKey ( const Type x ) key = x; /将当前结点的排序码修改为 xElement othe

2、rdata = x-otherdata; int operator = ( Type /判 this 与 x 相等int operator key; /判 this 小于或等于 xint operator ( Type /判 this 大于 xint operator x-key; /判 this 小于 xtemplate class dataList /用顺序表来存储待排序的元素,这些元素的类型是 Typeprivate:Element * Vector; /存储待排序元素的向量int MaxSize, CurrentSize; /最大元素个数与当前元素个数int Partition ( c

3、onst int low, const int high ) /用于快速排序的一次划分算法public:datalist ( int MaxSz = DefaultSize ) : MaxSize ( Maxsz ), CurrentSize (0) Vector = new Element MaxSize; /构造函数int length ( ) return CurrentSize; Element void swap ( Element x = y; y = temp; void Sort ( ); /排序静态链表类定义template class staticlinkList; /静态

4、链表类的前视声明 template class Element /静态链表元素类的定义friend class staticlinkList;private:Type key; /排序码,其它信息略int link; /结点的链接指针public:第 9 章 排序2Type getKey ( ) return key; /取当前结点的排序码void setKey ( const Type x ) key = x; /将当前结点的排序码修改为 xint getLink ( ) return link; /取当前结点的链接指针void setLink ( const int ptr ) link

5、= ptr; /将当前结点的链接指针置为 ptrtemplate class staticlinkList /静态链表的类定义private:Element *Vector; /存储待排序元素的向量int MaxSize, CurrentSize; /向量中最大元素个数和当前元素个数public:dstaticlinkList ( int Maxsz = DefaultSize ) : MaxSize ( Maxsz ), CurrentSize (0) Vector = new Element Maxsz; 9-1 什么是内排序? 什么是外排序? 什么排序方法是稳定的? 什么排序方法是不稳定

6、的? 【解答】内排序是排序过程中参与排序的数据全部在内存中所做的排序,排序过程中无需进行内外存数据传送,决定排序方法时间性能的主要是数据排序码的比较次数和数据对象的移动次数。外排序是在排序的过程中参与排序的数据太多,在内存中容纳不下,因此在排序过程中需要不断进行内外存的信息传送的排序。决定外排序时间性能的主要是读写磁盘次数和在内存中总的记录对象的归并次数。不稳定的排序方法主要有希尔排序、直接选择排序、堆排序、快速排序。不稳定的排序方法往往是按一定的间隔移动或交换记录对象的位置,从而可能导致具有相等排序码的不同对象的前后相对位置在排序前后颠倒过来。其他排序方法中如果有数据交换,只是在相邻的数据对

7、象间比较排序码,如果发生逆序(与最终排序的顺序相反的次序)才交换,因此具有相等排序码的不同对象的前后相对位置在排序前后不会颠倒,是稳定的排序方法。但如果把算法中判断逆序的比较“(或 void dataList : shaker_Sort ( ) /奇数趟对表 Vector 从前向后, 比较相邻的排序码, 遇到逆序即交换, 直到把参加比较排序码序列/中最大的排序码移到序列尾部。偶数趟从后向前, 比较相邻的排序码, 遇到逆序即交换, 直到把/参加比较排序码序列中最小的排序码移到序列前端。int i = 1, j; int exchange;while ( i = i; j- ) /逆向起泡if (

8、 Vectorj-1 Vectorj ) /发生逆序Swap ( Vectorj-1, Vectorj ); /交换, 最小排序码放在 Vectori-1处exchange = 1; /做“发生了交换”标志if ( exchange = 0 ) break; /当 exchange 为 0 则停止排序for ( j = i; j Vectorj+1 ) /发生逆序Swap ( Vectorj, Vectorj+1 ); /交换, 最大排序码放在 Vectorn-i处exchange = 1; /做“发生了交换”标志if ( exchange = 0 ) break; /当 exchange 为

9、 0 则停止排序i+;【解答 2】template void dataList : shaker_Sort ( ) int low = 1, high = CurrentSize-1, i, j; int exchange;while ( low Vectori+1 ) /发生逆序Swap ( Vectori, Vectori+1 ); /交换j = i; /记忆右边最后发生交换的位置 jhigh = j; /比较范围上界缩小到 j第 9 章 排序8for ( i = high; i low; i- ) /反向起泡if ( Vectori-1 Vectori ) /发生逆序Swap ( Vec

10、tori-1, Vectori ); /交换j = i; /记忆左边最后发生交换的位置 jlow = j; /比较范围下界缩小到 j9-5 如果待排序的排序码序列已经按非递减次序有序排列,试证明函数 QuickSort( )的计算时间将下降到 O(n2)。【证明】若待排序的 n 个对象的序列已经按排序码非递减次序有序排列,且设排序的时间代价为 T(n)。当以第一个对象作为基准对象时,应用一次划分算法 Partition,通过 n-1 次排序码比较,把只能把整个序列划分为:基准对象的左子序列为空序列,右子序列为有 n-1 个对象的非递减有序序列。对于这样的递归 QuickSort( )算法,其时

11、间代价为T(n) = (n-1) + T(n-1)= (n-1) + ( n-2) + T(n-2) = (n-1) + (n-2) + (n-3) + T(n-3) = = (n-1) + (n-2) + (n-3) + + 2 + T(1) = (n-1) + (n-2) + (n-3) + + 2 + 1= n(n-1)/2 = O(n2)9-6 在实现快速排序的非递归算法时,可根据基准对象,将待排序排序码序列划分为两个子序列。若下一趟首先对较短的子序列进行排序,试证明在此做法下,快速排序所需要的栈的深度为 O(log2n)。【解答】由快速排序的算法可知,所需递归工作栈的深度取决于所需划

12、分的最大次数。如果在排序过程中每次划分都能把整个待排序序列根据基准对象划分为左、右两个子序列。假定这两个子序列的长度相等,则所需栈的深度为S(n) = 1 + S(n/2) = 1 + 1 + S(n/4) = 2 + S(n/4)= 2 + 1 + S(n/8) = 3 + S(n/8)= = log2n + S(1) = log2n (假设 1 个对象的序列所用递归栈的深度为 0) 如果每次递归左、右子序列的长度不等,并且先将较长的子序列的左、右端点保存在递归栈中,再对较短的子序列进行排序,可用表示最坏情况的大 O 表示法表示。此时其递归栈的深度不一定正好是 log2n,其最坏情况为 O(

13、log2n)。 9-7 在实现快速排序算法时,可先检查位于两端及中点的排序码,取三者之中的数值不是最大也不是最小的排序码作为基准对象。试编写基于这种思想的快速排序算法,并证明对于已排序的排序码序列,该算法的计算时间为 O(nlog2n)。【解答】参看教科书9-8 在使用非递归方法实现快速排序时, 通常要利用一个栈记忆待排序区间的两个端点。那么能否用队列来代替这个栈? 为什么?【解答】可以用队列来代替栈。在快速排序的过程中,通过一趟划分,可以把一个待排序区间分为两个子区间,然后分别对这两个子区间施行同样的划分。栈的作用是在处理一个子区第 9 章 排序9间时,保存另一个子区间的上界和下界,待该区间

14、处理完成后再从栈中取出另一子区间的边界,对其进行处理。这个功能利用队列也可以实现,只不过是处理子区间的顺序有所变动而已。9-9 试设计一个算法, 使得在 O(n)的时间内重排数组, 将所有取负值的排序码排在所有取正值(非负值) 的排序码之前。【解答】template void reArrange ( dataListwhile ( i != j ) while ( Li.getKey( ) = 0 ) j-;swap ( Li, Lj );i+; j-;9-10 奇偶交换排序是另一种交换排序。它的第一趟对序列中的所有奇数项 i 扫描,第二趟对序列中的所有偶数项 i 扫描。若 Ai Ai+1,则

15、交换它们。第三趟有对所有的奇数项,第四趟对所有的偶数项,如此反复,直到整个序列全部排好序为止。(1) 这种排序方法结束的条件是什么? (2) 写出奇偶交换排序的算法。(3) 当待排序排序码序列的初始排列是从小到大有序,或从大到小有序时,在奇偶交换排序过程中的排序码比较次数是多少?【解答】(1) 设有一个布尔变量 exchange,判断在每一次做过一趟奇数项扫描和一趟偶数项扫描后是否有过交换。若 exchange = 1,表示刚才有过交换,还需继续做下一趟奇数项扫描和一趟偶数项扫描;若 exchange = 0,表示刚才没有交换,可以结束排序。(2) 奇偶排序的算法template void d

16、ataList : odd-evenSort ( ) int i, exchange;do exchange = 0;for ( i = 1; i Vectori+1 ) /相邻两项比较, 发生逆序exchange = 1; /作交换标记swap ( Vectori, Vectori+1 ); /交换for ( i = 0; i Vectori+1 ) /相邻两项比较, 发生逆序exchange = 1; /作交换标记swap ( Vectori, Vectori+1 ); /交换 while ( exchange != 0 );第 9 章 排序10(3) 设待排序对象序列中总共有 n 个对象

17、。序列中各个对象的序号从 0 开始。则当所有待排序对象序列中的对象按排序码从大到小初始排列时,执行 m = (n+1)/2 趟奇偶排序。当所有待排序对象序列中的对象按排序码从小到大初始排列时,执行 1 趟奇偶排序。在一趟奇偶排序过程中,对所有奇数项扫描一遍,排序码比较 (n-1)/2 次;对所有偶数项扫描一遍,排序码比较 n/2 次。所以每趟奇偶排序两遍扫描的结果,排序码总比较次数为 (n-1)/2 + n/2 = n-1。9-11 请编写一个算法,在基于单链表表示的待排序排序码序列上进行简单选择排序。【解答】采用静态单链表作为存储表示。用 Vector0作为表头结点,各待排序数据对象从Vec

18、tor1开始存放。算法的思想是每趟在原始链表中摘下排序码最大的结点(几个排序码相等时为最前面的结点),把它插入到结果链表的最前端。由于在原始链表中摘下的排序码越来越小,在结果链表前端插入的排序码也越来越小,最后形成的结果链表中的结点将按排序码非递减的顺序有序链接。Template void staticlinkList : selectSort ( ) int h = Vector0.link, p, q, r, s;Vector0.link = 0;while ( h != 0 ) /原始链表未扫描完p = s = h; q = r = 0; while ( p != 0 ) /扫描原始链表

19、, 寻找排序码最大的结点 sif ( Vectorp.data Vectors.data ) /记忆当前找到的排序码最大结点 s = p; r = q; q = p; p = Vectorp.link;if ( s = h ) h = Vectorh; /排序码最大的结点是原始链表前端结点, 摘下else Vectorr.link = Vectors.link; /排序码最大的结点是原始链表表中结点, 摘下Vectors.link = Vector0.link; /结点 s 插入到结果链表的前端Vector0.link = s;9-12 手工跟踪对以下各序列进行堆排序的过程。给出形成初始堆及每

20、选出一个排序码后堆的变化。(1) 按字母顺序排序:Tim, Dot, Eva, Rom, Kim, Guy, Ann, Jim, Kay, Ron, Jan (2) 按数值递增顺序排序:26, 33, 35, 29, 19, 12, 22 (3) 同样 7 个数字,换一个初始排列,再按数值的递增顺序排序:12, 19, 33, 26, 29, 35, 22【解答】 为节省篇幅,将用数组方式给出形成初始堆和进行堆排序的变化结果。阴影部分表示参与比较的排序码。请读者按照完全二叉树的顺序存储表示画出堆的树形表示。(1) 按字母顺序排序形成初始堆(按最大堆)0 1 2 3 4 5 6 7 8 9 10

21、Tim Dot Eva Rom Kim Guy Ann Jim Kay Ron Jan 第 9 章 排序11i=4 Tim Dot Eva Rom Ron Guy Ann Jim Kay Kim Jan i=3 Tim Dot Eva Rom Ron Guy Ann Jim Kay Kim Jan i=2 Tim Dot Guy Rom Ron Eva Ann Jim Kay Kim Jan i=1 Tim Ron Guy Rom Kim Eva Ann Jim Kay Dot Jan i=0 Tim Ron Guy Rom Kim Eva Ann Jim Kay Dot Jan 堆排序0 1

22、 2 3 4 5 6 7 8 9 10j=10 Jan Ron Guy Rom Kim Eva Ann Jim Kay Dot Tim 交换 Ron Rom Guy Kay Kim Eva Ann Jim Jan Dot Tim 调整j=9 Dot Rom Guy Kay Kim Eva Ann Jim Jan Ron Tim 交换 Rom Kim Guy Kay Dot Eva Ann Jim Jan Ron Tim 调整j=8 Jan Kim Guy Kay Dot Eva Ann Jim Rom Ron Tim 交换 Kim Kay Guy Jim Dot Eva Ann Jan Rom

23、 Ron Tim 调整j=7 Jan Kay Guy Jim Dot Eva Ann Kim Rom Ron Tim 交换 Kay Jim Guy Jan Dot Eva Ann Kim Rom Ron Tim 调整j=6 Ann Jim Guy Jan Dot Eva Kay Kim Rom Ron Tim 交换 Jim Jan Guy Ann Dot Eva Kay Kim Rom Ron Tim 调整j=5 Eva Jan Guy Ann Dot Jim Kay Kim Rom Ron Tim 交换 Jan Eva Guy Ann Dot Jim Kay Kim Rom Ron Tim

24、调整j=4 Dot Eva Guy Ann Jan Jim Kay Kim Rom Ron Tim 交换 Guy Eva Dot Ann Jan Jim Kay Kim Rom Ron Tim 调整j=3 Ann Eva Dot Guy Jan Jim Kay Kim Rom Ron Tim 交换 Eva Ann Dot Guy Jan Jim Kay Kim Rom Ron Tim 调整j=2 Dot Ann Eva Guy Jan Jim Kay Kim Rom Ron Tim 交换 Dot Ann Eva Guy Jan Jim Kay Kim Rom Ron Tim 调整j=1 Dot

25、 Ann Eva Guy Jan Jim Kay Kim Rom Ron Tim 交换 Ann Dot Eva Guy Jan Jim Kay Kim Rom Ron Tim 调整(2) 按数值递增顺序排序形成初始堆 (按最大堆)0 1 2 3 4 5 626 33 35 29 19 12 22 i=2 26 33 35 29 19 12 22 i=0 26 33 35 29 19 12 22 i=1 35 33 26 29 19 12 22 堆排序0 1 2 3 4 5 6j=6 22 33 26 29 19 12 35 交换 33 29 26 22 19 12 35 调整为堆j=5 12

26、29 26 22 19 33 35 交换 29 22 26 12 19 33 35 调整为堆第 9 章 排序12j=4 19 22 26 12 29 33 35 交换 26 22 19 12 29 33 35 调整为堆j=3 12 22 19 26 29 33 35 交换 22 12 19 26 29 33 35 调整为堆j=2 19 12 22 26 29 33 35 交换 19 12 22 26 29 33 35 调整为堆j=1 12 19 22 26 29 33 35 交换 12 19 22 26 29 33 35 调整为堆(3) 同样 7 个数字,换一个初始排列,再按数值的递增顺序排序

27、形成初始堆 (按最大堆)0 1 2 3 4 5 612 19 33 26 29 35 22 i=2 12 19 35 26 29 33 22 i=0 12 29 35 26 19 33 22 i=1 35 29 33 26 19 12 22 堆排序0 1 2 3 4 5 6j=6 22 29 33 26 19 12 35 交换 33 29 22 26 19 12 35 调整为堆j=5 12 29 22 26 19 33 35 交换 29 26 22 12 19 33 35 调整为堆j=4 19 26 22 12 29 33 35 交换 26 19 22 12 29 33 35 调整为堆j=3

28、12 19 22 26 29 33 35 交换 22 19 12 26 29 33 35 调整为堆j=2 12 19 22 26 29 33 35 交换 19 12 22 26 29 33 35 调整为堆j=1 12 19 22 26 29 33 35 交换 12 19 22 26 29 33 35 调整为堆9-13 如果只想在一个有 n 个元素的任意序列中得到其中最小的第 k (k0)个数据的序列,选最小数据需进行 n-1 次数据比较,以后每选一个数据,进行数据比较的次数,均需 log2n -1 次。例如,同样 12 个数据,第一次选最小的数据 6,需进行 11 次数据比较,以后选 7、9、

29、11 时,都是 log212 -1 = 2 次数据比较。9-14 希尔排序、简单选择排序、快速排序和堆排序是不稳定的排序方法, 试举例说明。【解答】(1) 希尔排序 512 275 275* 061 增量为 2 275* 061 512 275 增量为 1 061 275* 275 512 (2) 直接选择排序 275 275* 512 061 i = 1 061 275* 512 275 i = 2 061 275* 512 275 i = 3 061 275* 275 512 (3) 快速排序 512 275 275* 275* 275 512 (4) 堆排序 275 275* 061 1

30、70 已经是最大堆,交换 275 与 170 170 275* 061 275 对前 3 个调整 275* 170 061 275 前 3 个最大堆,交换 275*与 061 061 170 275* 275 对前 2 个调整 170 061 275* 275 前 2 个最大堆,交换 170 与 061 061 170 275* 275 9-15 设有 n 个待排序元素存放在一个不带表头结点的单链表中, 每个链表结点只存放一个元素, 头指针为 r。试设计一个算法, 对其进行二路归并排序, 要求不移动结点中的元素, 只改各链结点中的指针, 排序后 r 仍指示结果链表的第一个结点。 (提示:先对待

31、排序的单链表进行一次扫描, 将它划分为若干有序的子链表, 其表头指针存放在一个指针队列中。当队列不空时重复执行, 从队列中退出两个有序子链表, 对它们进行二路归并, 结果链表的表头指针存放到队列中。如果队列中退出一个有序子链表后变成空队列, 则算法结束。这个有序子链表即为所求。)【解答】(1) 两路归并算法template void staticlinkList : merge ( int ha; int hb; intif ( Vectorha.data void staticlinkList : merge_sort ( ) int r, s, t; Queue Q;if ( Vector

32、0.link = 0 ) return;s = Vector0.link; Q.Enqueue( s ); /链表第一个结点进队列while ( 1 ) t = Vectors.link; /结点 t 是结点 s 的下一个链中结点while ( t != 0 int *c = new datalist ; / c是存放计数排序结果的临时表for ( i = 0; i Vector 中各就各位c-Vector Vectori.count = Vectori;for ( i = 0; i Vectori; /结果复制回当前表对象中delete c;9-18 如果某个文件经内排序得到 80 个初始归

33、并段,试问(1) 若使用多路归并执行 3 趟完成排序,那么应取的归并路数至少应为多少?(2) 如果操作系统要求一个程序同时可用的输入/ 输出文件的总数不超过 15 个,则按多路归并至少需要几趟可以完成排序?如果限定这个趟数,可取的最低路数是多少?【解答】(1) 设归并路数为 k,初始归并段个数 m = 80,根据归并趟数计算公式 S = logkm = logk80 = 3 得: k380。由此解得 k3,即应取的归并路数至少为 3。(2) 设多路归并的归并路数为 k,需要 k 个输入缓冲区和 1 个输出缓冲区。1 个缓冲区对应 1 个文件,有 k +1 = 15,因此 k = 14,可做 1

34、4 路归并。由 S = logkm = log1480 = 2。即至少需 2 趟归并可完成排序。若限定这个趟数,由 S = logk80 = 2,有 80k 2,可取的最低路数为 9。即要在 2 趟内完成排序,进行 9 路排序即可。9-19 假设文件有 4500 个记录,在磁盘上每个页块可放 75 个记录。计算机中用于排序的内存区可容纳 450 个记录。试问:(1) 可建立多少个初始归并段?每个初始归并段有多少记录?存放于多少个页块中?(2) 应采用几路归并?请写出归并过程及每趟需要读写磁盘的页块数。【解答】(1) 文件有 4500 个记录,计算机中用于排序的内存区可容纳 450 个记录,可建

35、立的初始归并段有 4500450 = 10 个。每个初始归并段中有 450 个记录,存于 45075 = 6 个页块中。(2) 内存区可容纳 6 个页块,可建立 6 个缓冲区,其中 5 个缓冲区用于输入,1 个缓冲区用于输出,因此,可采用 5 路归并。归并过程如下:450 450 450 450 450 450 450 450 450 450 2250 2250 第 9 章 排序16共做了 2 趟归并,每趟需要读 60 个磁盘页块,写出 60 个磁盘页块。9-20 给出 12 个初始归并段,其长度分别为 30, 44, 8, 6, 3, 20, 60, 18, 9, 62, 68, 85。现要

36、做4 路外归并排序,试画出表示归并过程的最佳归并树,并计算该归并树的带权路径长度WPL。 【解答】设初始归并段个数 n = 12,外归并路数 k = 4,计算 (n-1) % (k-1) = 11 % 3 = 2 0,必须补 k-2-1 = 1 个长度为 0 的空归并段,才能构造 k 路归并树。此时,归并树的内结点应有(n- 1+1)/(k-1) = 12/3 = 4 个。WPL = (3+6+8)*3 + (9+18+20+30+44+60+62)*2 + (68+85)*1 = 51 + 486 + 153 = 6904500 0 3 6 8 9 18 20 30 44 60 62 68 850 3 6 89 18 20 30 44 60 62 68 85170 3 6 89 18 2017 30 44 60 6264 68 85 196413

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报