第10章 排序.docx
- 文档编号:30377579
- 上传时间:2023-08-14
- 格式:DOCX
- 页数:29
- 大小:27.45KB
第10章 排序.docx
《第10章 排序.docx》由会员分享,可在线阅读,更多相关《第10章 排序.docx(29页珍藏版)》请在冰豆网上搜索。
第10章排序
第10章排序
一、 基础知识题
10.1基本概念:
内排序,外排序,稳定排序,不稳定排序,顺串,败者树,最佳归并树。
【解答】⑴内排序和外排序若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序;反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序。
内部排序适用于记录个数不多的文件,不需要访问外存,而外部排序适用于记录很多的大文件,整个排序过程需要在内外存之间多次交换数据才能得到排序的结果。
⑵稳定排序和不稳定排序假设待排序记录中有关键字Ki=Kj(i≠j),且在排序前的序列中Ri领先于Rj。
经过排序后,Ri与Rj的相对次序保持不变(即Ri仍领先于Rj),则称这种排序方法是稳定的,否则称之为不稳定的。
⑶顺串外部排序通常经过两个独立的阶段完成。
第一阶段,根据内存大小,每次把文件中一部分记录读入内存,用有效的内部排序方法(如快速排序、堆排序等)将其排成有序段,这有序段又称顺串或归并段。
⑷败者树败者树为提高外部排序的效率而采用的,是由参加比赛的n个元素作叶子结点而得到的完全二叉树。
每个非叶(双亲)结点中存放的是两个子结点中的败者数据,而让胜者去参加更高一级的比赛。
另外,还需增加一个结点,即结点0,存放比赛的全局获胜者。
⑸最佳归并树在外部排序的多路平衡归并的k叉树中,为了提高效率减少对外存的读写次数,按哈夫曼树构造的k叉树称最佳归并树。
这棵树中只有度为0和度为k的结点。
若用m表示归并段个数,用nk表示度为k的个数,若(m-1)%(k-1)=0,则不需增加虚段,否则应附加k-(m-1)%(k-1)-1个虚段(即第一个k路归并使用(m-1)%(k-1)+1个归并段)。
10.2设待排序的关键字序列为(15,21,6,30,23,6′,20,17),试分别写出使用以下排序方法每趟排序后的结果。
并说明做了多少次比较。
(1)直接插入排序
(2)希尔排序(增量为5,2,1)(3)起泡排序
(4)快速排序(5)直接选择排序(6)锦标赛排序
(7)堆排序(8)二路归并排序(9)基数排序
【解答】
(1)直接插入排序
初始关键字序列:
15,21,6,30,23,6′,20,17
第一趟直接插入排序:
【15,21】
第二趟直接插入排序:
【6,15,21】
第三趟直接插入排序:
【6,15,21,30】
第四趟直接插入排序:
【6,15,21,23,30】
第五趟直接插入排序:
【6,6′,15,21,23,30】
第六趟直接插入排序:
【6,6′,15,20,21,23,30】
第七趟直接插入排序:
【6,6′,15,17,20,21,23,30】
(2)希尔排序(增量为5,2,1)
初始关键字序列:
15,21,6,30,23,6′,20,17
第一趟希尔排序:
6′,20,6,30,23,15,21,17
第二趟希尔排序:
6′,15,6,17,21,20,23,30
第三趟希尔排序:
6′,6,15,17,20,21,23,30
(3)起泡排序
初始关键字序列:
15,21,6,30,23,6′,20,17
第一趟起泡排序:
15,6,21,23,6′,20,17,30
第二趟起泡排序:
6,15,21,6′,20,17,23,30
第三趟起泡排序:
6,15,6′,20,17,21,23,30
第四趟起泡排序:
6,6′,15,17,20,21,30,23
第五趟起泡排序:
6,6′,15,17,20,21,30,23
(4)快速排序
初始关键字序列:
15,21,6,30,23,6′,20,17
第一趟快速排序:
【6′,6】15【30,23,21,20,17】
第二趟快速排序:
6′,6,15【17,23,21,20】30
第三趟快速排序:
6′,6,15,17【23,21,20】30
第四趟快速排序:
6′,6,15,17,【20,21】23,30
第五趟快速排序:
6,6′,15,17,20,21,30,23
(5)直接选择排序
初始关键字序列:
15,21,6,30,23,6′,20,17
第一趟直接选择排序:
6,21,15,30,23,6′,20,17
第二趟直接选择排序:
6,6′,15,30,23,21,20,17
第三趟直接选择排序:
6,6′,15,30,23,21,20,17
第四趟直接选择排序:
6,6′,15,17,23,21,20,30
第五趟直接选择排序:
6,6′,15,17,20,21,23,30
第六趟直接选择排序:
6,6′,15,17,20,21,23,30
第七趟直接选择排序:
6,6′,15,17,20,21,23,30
(6)锦标赛排序
初始关键字序列:
15,21,6,30,23,6′,20,17
6
6
6’
15
6
6’
17
15
21
6
30
23
6’
20
17
6’
15
6’
15
30
6’
17
15
21
∞
30
23
6’
20
17
15
15
23
15
30
23
17
15
21
∞
30
23
∞
20
17
锦标赛排序的基本思想是:
首先对n个待排序记录的关键字进行两两比较,从中选出n/2个较小者再两两比较,直到选出关键字最小的记录为止,此为一趟排序。
我们将一趟选出的关键字最小的记录称为“冠军”,而“亚军”是从与“冠军”比较失败的记录中找出,具体做法为:
输出“冠军”后,将(冠军)叶子结点关键字改为最大,继续进行锦标赛排序,直到选出关键字次小的记录为止,如此循环直到输出全部有序序列。
上面给出了排在前三个的记录,详细过程略。
(7)堆排序
初始关键字序列:
15,21,6,30,23,6′,20,17
初始堆:
6,17,6’,21,23,15,20,30
第一次调堆:
6’,17,15,21,23,30,20,【6】
第二次调堆:
15,17,20,21,23,30,【6’,6】
第三次调堆:
17,21,20,30,23,【15,6’,6】
第四次调堆:
20,21,23,30,【17,15,6’,6】
第五次调堆:
21,30,23,【20,17,15,6’,6】
第六次调堆:
23,30,【21,20,17,15,6’,6】
第七次调堆:
30,【23,21,20,17,15,6’,6】
堆排序结果调堆:
【30,23,21,20,17,15,6’,6】
(8)二路归并排序
初始关键字序列:
15,21,6,30,23,6′,20,17
二路归并排序结果:
15,17,20,21,23,30,6,6’
final↑↑first
(9)基数排序
初始关键字序列:
p→15→21→6→30→23→6′→20→17
第一次分配得到:
B[0].f→30→20←B[0].e
B[1].f→21←B[1].e
B[3].f→23←B[3].e
B[5].f→15←B[5].e
B[6].f→6→6’←B[6].e
B[7].f→17←B[7].e
第一次收集得到:
p→30→20→21→23→15→6→6’→17
第二次分配得到
B[0].f→6→6’←B[0].e
B[1].f→15→17←B[1].e
B[2].f→20→21→23←B[5].e
B[3].f→30←B[3].e
第二次收集得到
p→6→6’→15→17→20→21→23→30
基数排序结果:
6,6′,15,17,20,21,23,30
10.3在各种排序方法中,哪些是稳定的?
哪些是不稳定的?
并为每一种不稳定的排序方法举出一个不稳定的实例。
【解答】见下表:
排序方法
平均时间
最坏情况
辅助空间
稳定性
不稳定排序举例
直接插入排序
O(n2)
O(n2)
O
(1)
稳定
折半插入排序
O(n2)
O(n2)
O
(1)
稳定
二路插入排序
O(n2)
O(n2)
O(n)
稳定
表插入排序
O(n2)
O(n2)
O
(1)
稳定
起泡排序
O(n2)
O(n2)
O
(1)
稳定
直接选择排序
O(n2)
O(n2)
O
(1)
不稳定
2,2’,1
希尔排序
O(n1.3)
O(n1.3)
O
(1)
不稳定
3,2,2’,1(d=2,d=1)
快速排序
O(nlog2n)
O(n2)
O(log2n)
不稳定
2,2’,1
堆排序
O(nlog2n)
O(nlog2n)
O
(1)
不稳定
2,1,1’(极大堆)
2-路归并排序
O(nlog2n)
O(nlog2n)
O(n)
稳定
基数排序
O(d*(rd+n))
O(d*(rd+n))
O(rd)
稳定
10.4在执行某种排序算法的过程中出现了排序码朝着最终排序序列相反的方向移动,从而认为该排序算法是不稳定的,这种说法对吗?
为什么?
【解答】这种说法不对。
因为排序的不稳定性是指两个关键字值相同的元素的相对次序在排序前、后发生了变化,而题中叙述和排序中稳定性的定义无关,所以此说法不对。
对4,3,2,1起泡排序就可否定本题结论。
10.5在堆排序、快速排序和归并排序方法中:
(1)若只从存储空间考虑,则应首先选取哪种排序,其次选取哪种排序,最后选取哪种排序?
(2)若只从排序结果的稳定性考虑,则应选取哪种排序方法?
(3)若只从平均情况下排序最快考虑,则应选取哪种排序方法?
(4)若只从最坏情况下排序最快并且要节省内存考虑,则应选取哪种排序方法?
【解答】
(1)堆排序,快速排序,归并排序
(2)归并排序
(3)快速排序
(4)堆排序
10.6 设要求从大到小排序。
问在什么情况下冒泡排序算法关键字交换的次数为最多。
【解答】对冒泡算法而言,初始序列为反序时交换次数最多。
若要求从大到小排序,则表现为初始是上升序时关键字交换的次数为最多。
10.7快速排序的最大递归深度是多少?
最小递归深度是多少?
【解答】设待排序记录的个数为n,则快速排序的最小递归深度为log2n+1,最大递归深度n。
10.8我们知道,对于n个元素组成的顺序表进行快速排序时,所需进行的比较次数与这n个元素的初始排序有关。
问:
(1)当n=7时,在最好情况下需进行多少次比较?
请说明理由。
(2)当n=7时,给出一个最好情况的初始排序的实例。
(3)当n=7时,在最坏情况下需进行多少次比较?
请说明理由。
(4)当n=7时,给出一个最坏情况的初始排序的实例。
【解答】
(1)在最好情况下,每次划分能得到两个长度相等的子文件。
假设文件的长度n=2k-1,那么第一遍划分得到两个长度均为n/2的子文件,第二遍划分得到4个长度均为n/4的子文件,以此类推,总共进行k=log2(n+1)遍划分,各子文件的长度均为1,排序完毕。
当n=7时,k=3,在最好情况下,第一遍需比较6次,第二遍分别对两个子文件(长度均为3,k=2)进行排序,各需2次,共10次即可。
(2)在最好情况下快速排序的原始序列实例:
4,1,3,2,6,5,7。
(3)在最坏情况下,若每次用来划分的记录的关键字具有最大(或最小)值,那么只能得到左(或右)子文件,其长度比原长度少1。
因此,若原文件中的记录按关键字递减次序排列,而要求排序后按递增次序排列时,快速排序的效率与冒泡排序相同,其时间复杂度为O(n2)。
所以当n=7时,最坏情况下的比较次数为21次。
(4)在最坏情况下快速排序的初始序列实例:
7,6,5,4,3,2,1,要求按递增排序。
10.9判断下面的每个结点序列是否表示一个堆,如果不是堆,请把它调整成堆。
(1) 100,90,80,60,85,75,20,25,10,70,65,50
(2) 100,70,50,20,90,75,60,25,10,85,65,80
【解答】
(1)是堆
(2)不是堆。
调成大堆:
100,90,80,25,85,75,60,20,10,70,65,50
10.10 在多关键字排序时,LSD和MSD两种方法的特点是什么?
【解答】
最高位优先(MSD)法:
先对最高位关键字K0进行排序,将序列分成若干子序列,每个子序列中的记录都具有相同的K0值,然后,分别就每个子序列对关键字K1进行排序,按K1值不同再分成若干更小的子序列,……,依次重复,直至最后对最低位关键字排序完成,将所有子序列依次连接在一起,成为一个有序子序列。
最低位优先(LSD)法:
先对最低位关键字Kd-1进行排序,然后对高一级关键字Kd-2进行排序,依次重复,直至对最高位关键字K0排序后便成为一个有序序列。
进行排序时,不必分成子序列,对每个关键字都是整个序列参加排序,但对Ki(0<=i 另一方面,按LSD进行排序时,可以不通过关键字比较实现排序,而是通过若干次“分配”和“收集”来实现排序。 10.11 给出如下关键字序列321,156,57,46,28,7,331,33,34,63试按链式基数排序方法,列出一趟分配和收集的过程。 【解答】 按LSD法→321→156→57→46→28→7→331→33→34→63 分配[0][1][2][3][4][5][6][7][8][9] 32133341565728 33163467 收集→321→331→33→63→34→156→46→57→7→28 10.12 奇偶交换排序如下所述: 对于初始序列A[1],A[2],…,A[n],第一趟对所有奇数i(1<=i (1)分析这种排序方法的结束条件。 (2)写出用这种排序方法对35,70,33,65,24,21,33进行排序时,每一趟的结果。 【解答】 (1) 排序结束条件为没有交换为止 (2) 第一趟奇数: 35,70,33,65,21,24,33 第二趟偶数: 35,33,70,21,65,24,33 第三趟奇数: 33,35,21,70,24,65,33 第四趟偶数: 33,21,35,24,70,33,65 第五趟奇数: 21,33,24,35,33,70,65 第六趟偶数: 21,24,33,33,35,65,70 第七趟奇数: 21,24,33,33,35,65,70(无交换) 第八趟偶数: 21,24,33,33,35,65,70(无交换)结束 10.13 设某文件经内排序后得到100个初始归并段(初始顺串),若使用多路归并排序算法,并要求三趟归并完成排序,问归并路数最少为多少? 【解答】设归并路数为k,归并趟数为s,则s=logk100,因logk100=3,且k为整数,故k=5,即最少5路归并可以完成排序。 10.14 证明: 置换-选择排序法产生的初始归并段的长度至少为m。 (m是所用缓冲区的长度)。 【证明】由置换选择排序思想,第一个归并段中第一个元素是缓冲区中最小的元素,以后每选一个元素都不应小于前一个选出的元素,故当产生第一个归并段时(即初始归并段),缓冲区中m个元素中除最小元素之外,其他m-1个元素均大于第一个选出的元素,即当以后读入元素均小于输出元素时,初始归并段中也至少能有原有的m个元素。 证毕。 10.15 设有11个长度(即包含记录的个数)不同的初始归并段,它们所包含的记录个数分别为25,40,16,38,77,64,53,88,9,48,98。 试根据它们做4路平衡归并,要求: (1)指出总的归并趟数; (2)构造最佳归并树; (3)根据最佳归并树计算每一趟及总的读记录数。 【解答】 因为(11-1)%(4-1)=1,所以加“虚段”,第一次由两个段合并。 25 9 16 40 48 53 25 77 128 242 64 38 88 556 98 (1)三趟归并 (2)最佳归并树如图 (3)设每次读写一个记录 第一趟50次读写 总的读写次数: 2052 [(9+16)*3+(25+38+40)*2+ (48+53+64+77)*2+(88+98)]*2 10.16 对输入文件(101,51,19,61,3,71,31,17,19,100,55,20,9,30,50,6,90),当k=6时,使用置换-选择算法,写出建立的初始败者树及生成的初始归并段。 【解答】 2 5 71 4 0 3 1 3 1 61 1 19 1 51 1 101 1 1 初始败者树 初始归并段: R1: 3,19,31,51,61,71,100,101 R2: 9,17,19,20,30,50,55,90 R3: 6 10.17 选择题: 下面给出的四种排序方法中,排序过程中的比较次数与排序方法无关的是。 A.选择排序法B.插入排序法C.快速排序法D.堆排序法 【解答】A 10.18 选择题: 一个排序算法的时间复杂度与以下哪项有关。 A.排序算法的稳定性B.所需比较关键字的次数 C.所采用的存诸结构D.所需辅助存诸空间的大小 【解答】B 二、算法设计题 10.19 请编写一个算法,在基于单链表表示的关键字序列上进行简单选择排序。 voidLinkedListSelectSort(pointerhead); ∥本算法一趟找出一个关键字最小的结点,其数据和当前结点进行交换;若要交换指针∥则须记下当前结点和最小结点的前驱指针 {p=head->next; while(p) {q=p->next;r=p;∥设r是指向关键字最小的结点的指针 while(q! =null) {if(q->data q=q->next; } if(r! =p)r->data<-->p->data; p=p->next; } 10.20 设单链表头结点指针为L,结点数据为整型。 试写出对链表L按“直接插入方法”排序的算法。 voidLinkInserSort(LinkedListL) //本算法对单链表L按“直接插入方法”进行排序 {p=L->next->next;//链表至少一个结点,p初始指向链表中第二结点(若存在) L->next->next=null;//初始假定第一个记录有序 while(p! =null) {q=p->next;//q指向p的后继结点} s=L; while(s->next! =null&&s->next->data s=s->next;//向后找插入位置 p->next=s->next;s->next=p;//插入结点 p=q;//恢复p指向当前结点 } } 10.21 试设计一个双向冒泡排序算法,即在排序过程中交替改变扫描方向。 voidBubbleSort2(inta[],intn)∥相邻两趟向相反方向起泡的冒泡排序算法 {change=1;low=0;high=n-1;∥冒泡的上下界 while(low {change=0;∥设不发生交换 for(i=low;i if(a[i]>a[i+1]){a[i]<-->a[i+1];change=1;}∥有交换,修改标志change high--;∥修改上界 for(i=high;i>low;i--)∥气泡下沉,小元素上浮(向左) if(a[i]a[i-1];change=1;} low++;∥修改下界 }∥while}∥BubbleSort2 10.22 写出快速排序的非递归算法。 voidQuickSort(rectyper[n+1];intn) {∥对r[1..n]进行快速排序的非递归算法 typedefstruct{intlow,high;}node nodes[n+1];∥栈,容量足够大 intquickpass(rectyper[],int,int);∥函数声明 inttop=1;s[top].low=1;s[top].high=n; while(top>0) {ss=s[top].low;tt=s[top].high;top--; if(ss {k=quickpass(r,ss,tt); if(k-ss>1){s[++top].low=ss;s[top].high=k-1;} if(tt-k>1){s[++top].low=k+1;s[top].high=tt;} } }∥算法结束 intquickpass(rectyper[];ints,t) {i=s;j=t;rp=r[i];x=r[i].key; while(i {while(i if(i while(i if(i } r[i]=rp; return(i); }∥一次划分算法结束 [算法讨论]可对以上算法进行两点改进: 一是在一次划
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第10章 排序 10