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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

6 内部排序.docx

1、6 内部排序第6讲 内部排序本章主要考核内容如下:排序的基本概念,直接插入排序,折半插入排序,起泡排序,简单选择排序,希尔排序,快速排序,堆排序,二路归并排序,基数排序,各种内部排序算法的比较,内部排序算法的应用等。知识点分析(一) 排序的基本概念1排序的定义 1)排序:把一组无序地数据元素按照关键字值递增(或递减)地重新排列。如果排序依据的是主关键字,排序的结果将是唯一的;如果排序依据是次关键字,则排序的结构可能不唯一。2)稳定排序和不稳定排序:如果在待排序的记录序列中有多个数据元素的关键字值相同,经过排序后,这些数据元素的相对次序保持不变,则称这种排序算法是稳定的,否则称之为不稳定的。这往

2、往发生在利用次关键字排序的时候。如果按照次关键字排序,由于排序方法的不同,可能出现“对次关键字相同的两个元素,原来排在前面的元素,排序后排在了后面”。即原来顺序是“49,49”排序后变为“49,49”,这种排序方法称为“不稳定排序”,否则称为“稳定排序”。3)内部排序和外部排序:根据在排序过程中待排序的所有数据元素是否全部被放置在内存中,可将排序方法分为内部排序和外部排序两大类。内部排序是指在排序的整个过程中,待排序的所有数据元素全部被放置在内存中;外部排序是指由于待排序的数据元素个数太多,不能同时放置在内存,而需要将一部分数据元素放置在内存,另一部分数据元素放置在外存中,整个排序过程需要在内

3、外存之间多次交换数据才能得到排序的结果。4)排序过程的两项基本工作 比较两个关键字的大小; 将记录从一个存储位置移动到另一个存储位置。(有时可以用某种方法避免该步骤)说明: 1 任何排序方法都需要以上过程; 2 记录移动位置时,移动到的位置可能是最终位置,也可能不是,视不同的方法而定。2排序的分类 根据排序原则可将排序方法分为以下几类: 插入排序:将一个记录插入到一个已经排好序的有序表中,使得新表仍然有序。 交换排序:比较两个元素,如果不有序,则交换位置,每趟比较都会有某个记录存放在恰当位置。 选择排序:每一次从剩余元素中选择出一个最小(或最大)的,放在确定的位置。 归并排序:将两个或多个有序

4、表组合成一个新的有序表。 基数排序:是一种多关键字排序。3排序算法的效率 评价排序算法的效率主要有两点:一是在数据量规模一定的条件下,算法执行所消耗的平均时间,对于排序操作,时间主要消耗在关键字之间的比较和数据元素的移动上,因此我们认为,高效率的排序算法应该是尽可能少的比较次数和尽可能少的数据元素移动次数;二是执行算法所需要的辅助存储空间,辅助存储空间是指在数据量规模一定的条件下,除了存放待排序数据元素占用的存储空间之外,执行算法所需要的其他存储空间,理想的空间效率是算法执行期间所需要的辅助空间与待排序的数据量无关。4待排序序列的参考存储结构 待排序记录序列可以用顺序存储结构和链式存储结构表示

5、。我们将待排序的记录序列用顺序存储结构表示,即用一维数组实现。大部分算法,都可按照以下定义的数据类型设定。#define MAXSIZE 20typedef int KeyType ; /定义关键字类型为整数类型(也可以为其它类型)typedef struct KeyType key ; /关键字项 InfoType otherinfo ; /其它数据项 RecordType ;typedef struct RecordType rMAXSIZE +1 ; /r0闲置或者作为哨兵单元 int length ; /顺序表长度 SqList ; /顺序表类型真题解析1某内排序方法的稳定性是指( )

6、。A该排序算法不允许有相同的关键字记录B该排序算法允许有相同的关键字记录C平均时间为0(n log n)的排序方法D以上都不对【答案】D。【解析】待排序的文件中,若存在多个关键字相同的记录,经过排序后这些具有相同关键字的记录之间的相对次序保持不变,则该排序方法是稳定的;若具有相同关键字的记录之间的相对次序发生变化,则称这种排序方法是不稳定的。注意:排序算法的稳定性是针对所有输入实例而言的。即在所有可能的输入实例中,只要有一个实例使得算法不满足稳定性要求,则该排序算法就是不稳定的。 (二) 插入排序1直接插入排序 直接插入排序是一种最基本的排序算法,基本操作为:将一个记录插入到一个已经排好序的有

7、序表中,从而得到一个新的、长度增1的有序表。一般情况下,第i趟的操作为:在含有i-1个记录的有序子序列r1.i-1中插入一个新记录ri,变成含有i个记录的有序序列r1.i。设置r0为空值,从r1开始保存信息,可首先将待插入的记录ri复制到r0中,如下所示:r0r1r2r3.ri-1ri. 可把r0看成是ri的备份,以后从r1ri-1查找插入位置时可直接同r0比较,而且ri也可被覆盖了。因为ri复制到r0后,可认为已经空出了ri。考虑从后向前比较,只要ri-1ri,则ri的位置不必改变,否则(即ri1ri),则将ri-1移动到ri处,然后再比较ri-2和r0,依次等等。当最后找到一个比r0小的关

8、键字时,将r0复制到此关键字的后面一个位置,结束。具体算法为:void InsertSort(SqList &L) for (i = 2 ; i = L.length ; +i ) /第一个元素认为本身有序,所以从第二个元素开始即可 if ( L.ri.key L.ri-1.key ) / 当ri小于ri-1时,需排序,否则无需排序 L.r0 = L.ri ; /复制L.ri至L.r0,保证下面的for循环肯定能正常结束 for ( j = i -1 ; L.r0.key L.rj.key ; -j) L.rj+1 = L.rj ; /记录后移 L.rj+1 = L.r0 ; /插入到第一个小

9、于L.r0的元素L.rj的后面 举例:排序以下序列 49 38 65 97 76 13 27 49过程:(49) 38 65 97 76 13 27 49 (38) (38 49) 65 97 76 13 27 49 (65) (38 49 65) 97 76 13 27 49 (97) (38 49 65 97 ) 76 13 27 49 (76) (38 49 65 76 97) 13 27 49 (13) (13 38 49 65 76 97) 27 49 (27) (13 27 38 49 65 76 97 ) 49 (49) (13 27 38 49 49 65 76 97)该算法的

10、时间复杂度是O(n2), 属稳定排序。直接插入排序算法简单、容易实现。当待排序记录较少时,排序速度较快,但是,当待排序的记录数量较大时,大量的比较和移动操作将使直接插入排序算法的效率降低;然而,当待排序的数据元素基本有序时,直接插入排序过程中的移动次数大大减少,从而效率会有所提高。2折半插入排序 由于直接插入排序的基本操作是向一个有序表中进行查找和插入,因此,其中的“查找”操作可以利用“折半查找”来实现。由此改进的直接插入排序称为“折半插入排序”。由于查找是找不到需插入的记录的,因此有一个固定的结论:待插入位置是查找之后high指示的坐标之后的位置,即high1,则从high1到i-1的记录需

11、向后整体平移一个单位,变成high2i。算法入下:void BInsertSort(SqList &L) for (i = 2 ;i =L.length ; +i ) L.r0 = L.ri ; low = 1 ; high = i -1 ; while (low = high) mid = (low +high)/2 ; if (L.r0.key = high + 1 ; j -) L.rj+1 = L.rj ; L.rhigh+1 = L.r0 ; /high之后的第一个位置就是合适的位置 该算法的时间复杂度是O(n2),属稳定排序。折半插入排序比直接插入排序明显地减少了关键字间的“比较”

12、次数,但记录“移动”的次数不变。(三) 起泡排序1基本思想 起泡排序是交换排序中一种简单的排序方法。它的基本思想是对所有相邻记录的关键字值进行比效,如果是逆序(ajaj+1),则将其交换,最终达到有序化。其处理过程为:1 将整个待排序的记录序列划分成有序区和无序区,初始状态有序区为空,无序区包括所有待排序的记录。2 对无序区从前向后依次将相邻记录的关键字进行比较,若逆序则将其交换,从而使得关键字值小的记录向上“飘浮”(左移),关键字值大的记录好像石块,向下“堕落”(右移)。每经过一趟冒泡排序,都使无序区中关键字值最大的记录进入有序区,对于由n个记录组成的记录序列,最多经过n-1趟冒泡排序,就可

13、以将这n个记录重新按关键字顺序排列。 2起泡排序算法 1)原始的冒泡排序算法:对由n个记录组成的记录序列,最多经过(n-1)趟冒泡排序,就可以使记录序列成为有序序列,第一趟定位第n个记录,此时有序区只有一个记录;第二趟定位第n-1个记录,此时有序区有两个记录;以此类推,算法框架为:(假设用数组a存储待排序记录)void BubbleSort1 (DataType a,int n) for (i=n;i1;i-) for (j=1;ja.j+1.key) temp=aj;aj=aj+1;aj+1=temp; 2)改进的冒泡排序算法:在冒泡排序过程中,一旦发现某一趟没有进行交换操作,就表明此时待排

14、序记录序列已经成为有序序列,冒泡排序再进行下去已经没有必要,应立即结束排序过程。void BubbleSort2 (DataType a,int n) for (i=n;i1;i-) exchange=0; for (j=1;ja.j+1.key) temp=aj;aj=aj+1;aj+1=temp; exchange=1; if (exchange=0) break; 3)进一步地改进冒泡排序算法:在算法2)给出的冒泡排序算法的基础上,如果我们同时记录第i趟冒泡排序中最后一次发生交换操作的位置m(m1;i-) exchange=0; m=last; /初始将最后进行记录交换的位置设置成i-1

15、 for (j=1;ja.j+1.key) temp=aj;aj=aj+1;aj+1=temp; exchange=1; last=j; /记录每一次发生记录交换的位置 if (exchange=0)break; 冒泡排序比较简单,当初始序列基本有序时,冒泡排序有较高的效率,反之效率较低;其次冒泡排序只需要一个记录的辅助空间,用来作为记录交换的中间暂存单元;冒泡排序是一种稳定的排序方法。举例:利用冒泡法对以下序列进行排序。 (49,38 ,65 ,97 ,76, 13, 27, 49) n=8 第1趟:38 49 65 76 13 27 49 97 第2趟:38 49 65 13 27 49

16、76 97 第3趟:38 49 13 27 49 65 76 97 第4趟:38 13 27 49 49 65 76 97 第5趟:13 27 38 49 49 65 76 97 第6趟:13 27 38 49 49 65 76 97 第7趟:没有必要再比了,因为上一趟(第6趟)没有发生交换,这说明已经排序完毕。该算法的时间复杂度为O(n2),属于稳定排序。真题解析1. 在执行某个排序算法过程中,出现了排序关键字朝着最终排序序列相反的方向的移动,从而认为该算法是不稳定的。这种说法对么?为什么? 【解析】这种看法不对。本题的叙述与稳定性的定义无关,不能据此来判断排序中的稳定性。例如 5,4,1,

17、2,3在第一趟冒泡排序后得到4,1,2,3,5。其中4 向前移动,与其最终位置相反。但冒泡排序是稳定排序。快速排序中无这种现象。(四) 简单选择排序1基本思想 简单选择排序的基本思想是:每一趟在n-i+1(i=1,2,3,.,n-1)个记录中选取关键字最小的记录作为有序序列中的第i个记录。它的具体实现过程为:1 将整个记录序列划分为有序区域和无序区域,有序区域位于最左端,无序区域位于右端,初始状态有序区域为空,无序区域含有待排序的所有n个记录。2 设置一个整型变量index,用于记录在一趟的比较过程中,当前关键字值最小的记录位置。开始将它设定为当前无序区域的第一个位置,即假设这个位置的关键字最

18、小,然后用它与无序区域中其他记录进行比较,若发现有比它的关键字还小的记录,就将index改为这个新的最小记录位置,随后再用aindex.key 与后面的记录进行比较,并根据比较结果,随时修改index的值,一趟结束后index中保留的就是本趟选择的关键字最小的记录位置。3 将index位置的记录交换到无序区域的第一个位置,使得有序区域扩展了一个记录,而无序区域减少了一个记录。不断重复 2、3,直到无序区域剩下一个记录为止。此时所有的记录已经按关键字从小到大的顺序排列就位。2简单选择排序算法 算法如下:void selecsort ( DataType a, int n) for( i=1; i

19、n; i+) /对n个记录进行n-1趟的简单选择排序 index=i; /初始化第i趟简单选择排序的最小记录指针 for (j=i+1;j=n;j+) /搜索关键字最小的记录位置 if (aj.key1的方法,则可以使较小的数向前推进是“跳跃式”进行,故可以提高排序效率。方法:将整个序列分成若干子序列,对各个子序列进行直接插入排序,得到一趟希尔排序序列;然后缩短步长,重复以上动作,直到步长为1。具体步骤如下: 先取一正整数d(d 第一次分组,取dn/24,则对序列分组为: 对每个子序列直接插入排序得(4组): 72 16 15 23 94 73 71 68 2 第二次分组,取d = 2(原来的

20、一半),对序列分组为: 对每个子序列直接插入排序得(2组): 15 16 71 23 72 68 94 73 3 第三次分组,取d1(原来的一半),序列为一组,直接插入排序得: 15 16 23 68 71 72 73 94 排序完成。说明: 步长的选择是迄今为止还没有完全解决的。该算法的时间复杂度O(n1.5) ,是不稳定排序(因为存在着跳跃)。真题解析1. 给出一组关键字T=(12,2,16,30,8,28,4,10,20,6,18),写出用下列算法从小到大排序时第一趟结束时的序列; (1) 希尔排序(第一趟排序的增量为5) (2) 快速排序(选第一个记录为枢轴(分隔)(3) 链式基数排序

21、(基数为10)【解析】 (1)一趟希尔排序: 12,2,10,20,6,18,4,16,30,8,28 ( D=5) (2)一趟快速排序:6,2,10,4,8,12,28,30,20,16,18 (3)链式基数排序LSD 0123456789 分配 30 12 4 16 8 10 2 6 28 20 18 收集:301020122416682818(六) 快速排序1基本思想 快速排序是对冒泡排序的一种改进,其基本思想是:通过一趟排序将待排序的记录分成独立的两部分,其中一部分记录的关键字比另一部分的关键字小。然后对这两部分再继续排序,一直达到整个序列有序。 设待排序序列为L.r1,L.r2,.,

22、L.rn,首先任意选取一个记录(通常选择第一个记录L.r1)作为支点(pivot),然后按照下述原则排列其余记录:将所有关键字比L.r1.key小的记录都安排在它的位置之前,将所有关键字比L.r1.key大的记录都安排在它的位置之后。可以发现,在安置的过程中,L.r1的确切位置将被最终确定。设该支点(pivot)最后确定的位置为i,则将序列分割为左右两部分。这个过程称为一趟快速排序。2具体步骤 设待排序序列用数组elow.high保存。设置两个指针low和high,分别指向数组的开始位置和终止位置。设支点记录为elow,并将之暂存于t。首先,从high的位置向前搜索,找到第一个小于t的记录,将

23、这个记录和elow的值交换;然后,从low所指向的位置向后搜索,找到第一个值大于t的记录,将这个记录和ehigh的值交换。重复以上步骤,直到lowhigh。完成一趟排序,low(或者high)指向的位置就是第一个元素的确切位置。(从两边向中间“夹挤”)。第一趟完成后,确定了第一个元素的确切位置,同时生成了两个子序列,然后再对这两个序列使用同样的办法,最终实现整个序列的有序。举例:利用快速排序法对以下序列进行排序: (49,38 ,65 ,97 ,76, 13, 27, 49) 过程如下: 初始状态: high向左移动(high-),直到找到小于t(49)的关键字27,将27的值赋给elow,如

24、下:接着low开始向右移动(low+),直到找到大于t(49)的关键字65,将65的值赋给ehigh,如下: high继续左移(high-),直到一个小于t的数13,将之赋给elow,如下:low继续右移(low+),直到找到大于t(49)的关键字97,将之赋给ehigh,如下:high继续左移(high-),没有找到比t(49)还小的数,但是由于出现了highlow的情况,结束左移。如下:此时low(或者high)指向的位置就是第一个元素的确定位置:elowt;经过以上一趟快速排序,可将原序列分为了两个序列,同时确定关键字49的确切位置,如下: 27, 38, 13 49 76, 97, 6

25、5, 49下面再分别对两个子需类进行快速排序,得最终结果: 13 27 38 49 49,65 76 97 49 65则最终得有序序列:(13, 27, 38, 49, 49, 65 76, 97 )说明:在一趟排序中,支点最后才确定位置,故只需最后一步赋值即可,中间不必交换。即,虽然快速排序是交换排序的一种,但是可以不用交换操作即可实现)该算法由于有不相邻元素交换,故是不稳定排序,其时间复杂度为O(nlog2n),是内排序中最好的方法之一。真题解析1. 我们知道,对于n个元素组成的线性表进行快速排序时,所需进行的比较次数与这n个元素的初始排序有关。问: (1) 当n=7时,在最好情况下需进行

26、多少次比较?请说明理由。(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) 在最坏情况下,若每次用来划

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

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