数据结构-(9)课件.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《数据结构-(9)课件.ppt》由用户(三亚风情)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课件
- 资源描述:
-
1、第第9 9章章 排序排序 9.1 排序基本概念排序基本概念 9.2 插入排序插入排序 9.3 交换排序交换排序 9.4 选择排序选择排序 9.5 归并排序归并排序 9.6 基数排序基数排序 9.7 内部排序总结内部排序总结 9.8 有关排序算法的有关排序算法的C语言源程序语言源程序 9.9 多路归并用于外排序的简介多路归并用于外排序的简介第第9章章 排序排序返回主目录返回主目录第第9 9章章 排序排序第第9章章排序排序9.1 排序基本概念排序基本概念 排序(sorting)又称分类,意指把一批杂乱无章的数据序列重新排列成有序序列。按待排序的记录的数量多少,排序过程中涉及的存储介质不同,排序方法
2、分为两大类:内部排序和外部排序。内部排序是指待排序的记录存放在计算机内存之中;外部排序是指待排序的记录数量很大,以至于内存容纳不下而存放在外存储器之中,排序过程需要访问外存。排序的依据可以是记录的主关键字,也可以是次关键字,甚至是若干数据项的组合。为了讨论方便,把排序所依据的数据项统称排序关键字,简称关键字。第第9 9章章 排序排序 假设含有n个记录的序列为R1,R2,Rn,其相应的关键字序列为K1,K2,Kn,所谓排序就是将记录按关键字非递减(或非递增)的顺序重新排列起来。在待排序的记录中若有多个相同的关键字,在用某种方法排序之后,这些关键字相同的记录相对先后次序不变,则称这种排序方法是稳定
3、的;否则是不稳定的。本章所介绍的内部排序方法包括插入排序、交换排序、选择排序、归并排序和基数排序。前四类排序是通过比较关键字的大小决定记录先后次序,也称为比较排序。基数排序是不经关键字比较的排序方法。为了讨论方便,在此把排序关键字假设为整型。记录的结构定义为:第第9 9章章 排序排序 struct node int key;/*排序关键字域*/int oth;/*其它域,根据需要自己设定*/第第9 9章章 排序排序9.2 插入排序插入排序 9.2.1 直接插入排序直接插入排序 直接插入排序(straight insertion sort)是一种最简单的排序方法。它的基本操作是将一个记录插入到一
4、个长度为m(假设)的有序表中,使之仍保持有序,从而得到一个新的长度为m1的有序表。算法思路:设有一组关键字K1,K2,Kn,排序开始就认为K1是一个有序序列;让K2插入上述表长为1的有序序列,使之成为一个表长为2的有序序列;然后让K3插入上述表长为2的有序序列,使之成为一个表长为3的有序序列;依次类推,最后让Kn插入上述表长为n-1的有序序列,得一个表长为n的有序序列。第第9 9章章 排序排序第第9 9章章 排序排序 例9.1 设有一组关键字序列55,22,44,11,33,这里n=5,即有5个记录。如图 9.1 所示。请将其按由小到大的顺序排序在具体实现Ki 向前边插入时,有两种方法。一种方
5、法是让Ki与K1,K2,顺序比较;另一种方法是Ki与 Ki-1,Ki-2 倒着比较。这里选用后一种方法。用一维数组r做存储结构,n表示记录个数,MAXSIZE为常量,且MAXSIZEn。则算法如下:算法 9.1void stinsort(struct node rMAXSIZE,int n)for(i=2;i r0.key)rj+1=rj;j-;rj+1=r0;/*将r0即原ri记录内容,插到rj后一位置*/*stinsort*/此算法外循环n-1次,在一般情况下内循环平均比较次数的数量级为(n),所以算法总时间复杂度为(n2)。由于比较过程中,当Kj 与K0相等时并不移动记录,因此直接插入排
6、序方法是稳定的。直接插入排序也可用单链表做存储结构。第第9 9章章 排序排序 当某结点i的关键字Kj与前边有序表比较时,显然先与K1 比较,再与K2比较,即从链表表头结点开始向后逐一比较更合适。另外,直接插入排序在原关键字序列基本有序或n值较小时,它是一种最常用的排序方法,它的时间复杂度接近于O(n)。但是,当n值又较大时,此方法就不再适用。第第9 9章章 排序排序 9.2.2 折半插入排序折半插入排序 当直接插入排序进行到某一趟时,对于ri.key来讲,前面i-1个记录已经按关键字有序。此时不用直接插入排序的方法,而改为折半查找,找出ri.key应插的位置,然后插入。这种方法就是折半插入排序
7、(binary insertion sort)。算法如下:算法 9.2 void binasort(struct node rMAXSIZE,int n)for(i=2;i=n;i+)ZK(r0=ri;l=1;h=i-1;第第9 9章章 排序排序while(l=h)mid=(l+h)/2;if(r0.key=l;j-)rj+1=rj;rl=r0;/*binasort*/第第9 9章章 排序排序 9.2.3 希尔排序希尔排序 希尔排序(shell sort)是D希尔(D.L.Shell)提出的“缩小增量”的排序方法。它的作法不是每次一个元素挨一个元素的比较,而是初期选用大跨步(增量较大)间隔比较
8、,使记录跳跃式接近它的排序位置;然后增量缩小;最后增量为 1,这样记录移动次数大大减少,提高了排序效率。希尔排序对增量序列的选择没有严格规定。算法思路:先取一个正整数d1(d1 n),把全部记录分成d1 个组,所有距离为d1的倍数的记录看成一组,然后在各组内进行插入排序;然后取d2(d2=1),即所有记录成为一个组为止。一般选d1约为n/2,d1为 d1/2,d3为d1/2,d1=1。第第9 9章章 排序排序 例92 有一组关键字76,81,60,22,98,33,12,79,将其按由小到大的顺序排序。这里n=8,取d1=4,d2=2,d3=1,其排序过程如图9.2所示。算法实现见算法9.3。
9、算法 9.3 void shellsort(struct node rMAXSIZE,int n)k=n/2;/*k值代表前文中的d值*/while(k=1)for(i=k+1;ir0.key)&(j=0)rj+k=rj;j=j-k;rj+k=r0;ZK)k=k/2;ZK)/*shellsort*/第第9 9章章 排序排序第第9 9章章 排序排序 此算法外层循环是增量由n/2逐步缩小到的循环。for所构成的循环是针对某一特定的增量k,进行大跨步跳跃式的插入排序。例如k=2时,关键字分成二组,见图9.2的第2行,其中第1组是76,12,98,60,排序后的结果为12,60,76,98,插入操作如
10、下:i=3 K1=76有序,K3=12向前插;i=5 12,76有序,K5=98不移动;i=7 12,76,98有序,K7=60向前插;第第9 9章章 排序排序 第2组是33,22,81,79,排序后的结果为22,33,79,81,插入操作如下:HT5”SS i=4 K2=33 有序,K2=22向前插;i=6 22,33 有序,K6=81不移动;i=8 22,33,81有序,K8=79向前插;对 整 个 文 件 来 说,排 序 结 果 实 际 上 为:12,22,60,33,76,79,98,81。当K=1时,此算法就等同于直接插入排序方法。由于前边大增量的处理,使关键字大体有序,因此最后一趟
11、排序移动的记录少,处理速度快。第第9 9章章 排序排序 希尔排序的分析是一个复杂的问题,因为它的时间是所选定的“增量序列”的函数,这涉及到数学上一些尚未解决的难题。到目前为止,没有人找到一种最好的增量序列。有人在大量实验基础上推导出,希尔排序的时间复杂度为O(n1.3)。如果对关键字序列6,7,51,2,52,8进行希尔排序,可以看出希尔排序是不稳定的。第第9 9章章 排序排序9.3 交换排序交换排序 9.3.1 冒泡排序冒泡排序 冒泡排序(bubble sort)是一种人们熟知的、最简单的交换排序方法。在排序过程中,关键字较小的记录经过与其它记录的对比交换,像水中的气泡向上冒出一样,移到序列
12、的首部,故称此方法为冒泡排序法。排序的算法思路是:(1)让j取n至2,将rj.key与rj-1.key比较,如果rj.keyi;j-)if(rj.keyrj-1.key)第第9 9章章 排序排序第第9 9章章 排序排序 x=rj;rj=ri;ri=x;tag=1;ZK)i+;while(tag=1&in);/*bubblesort*/算法中tag为标志变量,当某一趟处理过程中未进行过记录交换时,tag值应为0;若发生过交换,则tag值为1。所以外循环结束条件是:或者tag=0,已有序;或者i=n,已进行了n-1趟处理。该算法的时间复杂度为O(n2)。但是,当原始关键字序列已有序时,只进行一趟比
13、较就结束,此时时间复杂度为O(n)。第第9 9章章 排序排序 9.3.2 快速排序快速排序 快速排序由霍尔(Hoare)提出,它是一种对冒泡排序的改正。由于其排序速度快,故称快速排序(quick sort)。快速排序方法的实质是将一组关键字K1,K2,Kn 进行分区交换排序。其算法思路是:(1)以第一个关键字K1为控制字,将 K1,K2,Kn 分成两个子区,使左区所有关键字小于等于K1,右区所有关键字大于等于K1,最后控制字居两个子区中间的适当位置。在子区内数据尚处于无序状态。(2)将右区首、尾指针(记录的下标号)保存入栈,对左区进行与第(1)步相类似的处理,又得到它的左子区和右子区,控制字居
14、中。第第9 9章章 排序排序 (3)重复第(1)、(2)步,直到左区处理完毕。然后退栈对一个个子区进行相类似的处理,直到栈空。由以上三步可以看出:快速排序算法总框架是进行多趟的分区处理;而对某一特定子区,则应把它看成又是一个待排序的文件,控制字总是取子区中第一个记录的关键字。现在设计一个函数hoare,它仅对某一待排序文件进行左、右子区的划分,使控制字居中;再设计一个主体框架函数quicksort,在这里多次调用hoare函数以实现对整个文件的排序。例9.4 HT设有一组关键字46,56,14,43,95,19,18,72,这里n=8。试用快速排序方法由小到大进行排序。1)分区处理函数hoar
15、e第第9 9章章 排序排序 思路:首先用两个指针i、j分别指向首、尾两个关键字,i=1,j=8。第一个关键字46作为控制字,该关键字所属的记录另存储在一个x变量中。从文件右端元素rj.key开始与控制字x.key相比较,当rj.key大于等于x.key时,rj不移动,修改j指针,j-,直到rj.keyx.key,把记录ri移到文件右边j所指向的位置;再到文件右边修改j指针,j-。重复上面的步骤,直到i=j,此处就是控制字记录x所在的位置。第第9 9章章 排序排序 至此将文件分成了左、右两个子区,其具体操作见图9.4。算法如算法 9.5(假设某区段文件,指向第一个记录的指针为l,指向最后一个记录
16、的指针为h)。算法 9.5 int hoare(struct node rMAXSIZE,int l,int h)i=1;j=h;x=ri;do while(i=x.key)j-;if(ij)ri=rj;i+;第第9 9章章 排序排序第第9 9章章 排序排序 while(ij)&(ri.key=x.key)i+;if(i=j)rj=ri;j-;while(ij);ri=x;return(i);/*hoare*/2)快速排序主体框架算法 对一个文件,令l=1,h=n,调用hoare,求出i;然后右子区l=i+1,h=n,入栈,对左子区令l=1,h=i-1,再次调用hoare,如此反复,直到全部文
17、件记录处理完毕。图9.5中第1行表示对例9.4的数据进行过一次分区处理之后的结果,在此基础上经过多次调用hoare后,最后得出第5行的结果。第第9 9章章 排序排序第第9 9章章 排序排序下面给出快速排序的递归算法和非递归算法。非递归算法:算法 9.6void quicksort1(struct node rMAXSIZE,int n)/*int sn2;辅助栈s*/l=1;h=n;tag=1;top=0;do while(lh)i=hoare(r,l,h);top+;stop0=i+1;stop1=h;h=i-1;第第9 9章章 排序排序else l=stop0;h=stop1;top-;w
18、hile(tag=1);/*quicksort1*/递归算法:算法 9.7void quicksort2(struct node r,int l,int h)if(lh)i=hoare(r,l,h);/*划分两个区*/第第9 9章章 排序排序quicksort2(r,l,i-1);/*对左分区快速排序*/quicksort2(r,i+1,h);/*对右分区快速排序*/*quicksort2*/在主程序调用非递归算法比较简单易懂。若要调用递归算法,因函数的形参不同,需做预处理。主程序的主要操作如下:调用递归函数 调用非递归函数 creat(r,n);creat(r,n);l=1;h=n;quic
19、ksort1(r,n);quicksort2(r,l,h);输出r;输出r;第第9 9章章 排序排序 3)快速排序算法空间时间及稳定性分析 快速排序的非递归算法引用了辅助栈,它的深度为log2n。假设每一次分区处理所得的两个子区长度相近,那么可入栈的子区长度分别为:n/21,n/22,n/23,n/2k,又因为n/2k=1,所以k=log2n。分母中2的指数恰好反映出需要入栈的子区个数,它就是log2n,也即栈的深度。在最坏情况下,比如原文件关键字已经有序,每次分区处理仅能得到一个子区。可入的子区个数接近n,此时栈的最大深度为n。快速排序主体算法时间运算量约O(log2n),划分子区函数运算量
20、约O(n),所以总的时间复杂度为O(n log2n),它显然优于冒泡排序O(n2)。可是算法的优势并不是绝对的,试分析,当原文件关键字有序时,快速排序时间复杂度是O(n2),这种情况下快速排序不快。第第9 9章章 排序排序 而这种情况的冒泡排序是O(n),反而很快。在原文件记录关键字无序时的多种排序方法中,快速排序被认为是最好的一种排序方法。例9.5 试对6,7,51,2,52,8进行快速排序。排序过程简述如下:67512528初始状态 52 7 51 6 7 8 2 52 516 7 8 2 52 51 6 7 8 最后状态第第9 9章章 排序排序9.4 选择排序选择排序 9.4.1 简单选
21、择排序简单选择排序 简单选择排序(simple selection sort)也是直接选择排序。此方法在一些高级语言课程中做过介绍,是一种较为容易理解的方法。对于一组关键字K1,K2,Kn,将其由小到大进行简单排序的具体思路是:首先从K1,K2,Kn中选择最小值,假如它是Kz,则将Kz与K1对换;然后从K2,K3,Kn中选择最小值Kz,再将Kz与Kz对换;如此进行选择和调换n-2趟。第(n-1)趟,从Kn-1、Kn中选择最小值Kz,将Kz与Kn-1对换,最后剩下的就是该序列中的最大值,一个由小到大的有序序列就这样形成的。该算法的时间复杂度为O(n2)。第第9 9章章 排序排序 由此可见,对于n
22、个记录的关键字,需要处理n-1趟;而在每趟之中,又有一个内循环。图9.6是一个有5个关键字3,4,1,5,2的简单选择排序过程的示意图。假设用变量z记下较小值的下标,则算法如算法 9.8。算法 9.8 void sisort(struct node rMAXSIZE,int n)for(i=1;in;i+)z=i;for(j=i+1;j=n;j+)第第9 9章章 排序排序第第9 9章章 排序排序 if(rj.keyrz.key)z=j;x=ri;ri=rz;rz=x;/*sisort*/第第9 9章章 排序排序 9.4.2 堆排序堆排序 除了简单选择排序之外,还有树形选择排序(锦标赛排序)。1
23、964年威洛姆斯(J.Willioms)提出了进一步改正的排序方法,即堆排序(heap sort)。堆是n个元素的有限序列k1,k2,kn,它当且仅当满足如下关系:ki=k2i ki=k2i+1 i=1,2,这是一个上小、底大的堆。若是一个上大、底小的堆,只需把“=”即可。堆是一种数据元素之间的逻辑关系,常用向量做存储结构。对于第 6 章中介绍的满二叉树,当对它的结点由上而下,第第9 9章章 排序排序 自左至右编号之后,编号为i的结点是编号为2i和2i+1结点的双亲。反过来讲,结点2i是结点i的左孩子,结点2i+1是结点i的右孩子。图9.7表示完全二叉树和它在向量中的存储状态。结点编号对应向量
24、中的下标号。用堆的概念分析向量中的数据,它显然满足(上小、底大)堆的关系。不难看出,满足堆的逻辑关系的一组数据,可画成二叉树的形状,并且它是一棵完全二叉树树形。因此,也可借助完全二叉树来描述堆的概念。若完全二叉树中任一非叶子结点的值小于等于(或大于等于)其左、右孩子结点的值,则从根结点开始按结点编号排列所得的结点序列就是一个堆。在图9.8中(a)、(c)是堆,(b)、(d)不是堆。第第9 9章章 排序排序第第9 9章章 排序排序第第9 9章章 排序排序 堆排序的思路是:把n个记录存于向量r之中,把它看成完全二叉树,此时关键字序列不一定满足堆的关系。堆排序大体分两步处理。(1)初建堆。从堆的定义
25、出发,当i=1,2,n/2时应满足ki=k2i和ki=k2i+1。所以先取i=n/2(它一定是第n个结点双亲的编号),将以i结点为根的子树调整为堆;然后令i=i-1,将以i结点为根的子树调整为堆。此时可能会反复调整某些结点,直到i=1为止,堆初步建成。(2)堆排序。首先输出堆顶元素(一般是最小值),让堆中最后一个元素上移到原堆顶位置,然后恢复堆。因为经过第一步输出堆顶元素的操作后,往往破坏了堆关系,所以要恢复堆;重复执行输出堆顶元素、堆尾元素上移和恢复堆的步骤,直到全部元素输出完为止。第第9 9章章 排序排序 例 9.6 设 有 n 个 记 录(n=8)的 关 键 字 是46,55,13,42
展开阅读全文