数据结构03排序.ppt

上传人:小飞机 文档编号:6296815 上传时间:2023-10-14 格式:PPT 页数:80 大小:1.35MB
返回 下载 相关 举报
数据结构03排序.ppt_第1页
第1页 / 共80页
数据结构03排序.ppt_第2页
第2页 / 共80页
数据结构03排序.ppt_第3页
第3页 / 共80页
数据结构03排序.ppt_第4页
第4页 / 共80页
数据结构03排序.ppt_第5页
第5页 / 共80页
点击查看更多>>
资源描述

《数据结构03排序.ppt》由会员分享,可在线阅读,更多相关《数据结构03排序.ppt(80页珍藏版)》请在三一办公上搜索。

1、,数 据 结 构(Data Structure),第三章 排 序(Sorting),第三章 排序,3.1 排序的基本概念3.2 简单排序方法3.3 先进法排序方法3.4 基数排序3.5 各种排序方法的综合比较,第三章 排序,待排序数据元素(记录)的存储结构:typedef int KeyType/定义关键字类型为整型typedef struct KeyType key;/关键字项 InfoType otherinfo;/其他数据项RcdType;/记录类型本章的排序图例只标出了记录的关键字。,3.1 排序的基本概念,3.1.1 排序的定义3.1.2 排序的特性稳定性与不稳定性3.1.3 排序的

2、分类3.1.4 内排序的特点3.1.5 选择排序法,3.1 排序的基本概念,3.1.1 排序的定义简单定义:排序是按照关键字的非递减或非递增顺序对一组记录重新进行整队(或排列)的操作。数学定义:假设含有n个记录的序列为:r1,r2,rn(3-1)它们的关键字相应为k1,k2,kn,对式(3-1)的记录序列进行排序就是要确定序号1,2,n的一种排列p1,p2,pn使其相应的关键字满足如下的非递增(减)关系:kp1 kp2 kpn(3-2)也就是使式(3-2)的记录序列重新排列成一个按关键字有序的序列rp1 rp2 rpn(3-3),3.1 排序的基本概念,3.1.2 排序的特性稳定性与不稳定性当

3、待排记录中的关键字ki(1,2,n)都不相同时,则任何一个记录的无序序列经排序后得到的结果是惟一的。简单地说,稳定性排序-数据排序过后能使值相同的数据,保持原顺序中之相对位置。反之,则称为“不稳定性排序”。若排序的序列中存在两个或两个以上关键字相等的记录时,则排序得到的记录序列的结果不惟一。假设ki=kj(1i n,1jn,ij),且在排序前的序列中 ri 领先于rj(即ij)。若在排序后的序列中ri 总是领先于rj,则称所用的排序方法是稳定的;反之,若可能使排序后的序列中 rj领先于ri,则称所用的排序方法是不稳定的。,3.1.2 排序的特性稳定性与不稳定性,3.1.3 排序的分类,根据在排

4、序的过程涉及的存储器不同,排序方法可分为两类:1.内部排序(Internal Sort):在排序进行的过程中不使用计算机外部存储器的排序过程。选择排序插入排序起泡排序快速排序归并排序堆排序基数排序2.外部排序(External Sort):在排序进行的过程中需要对外存进行访问的排序过程。,3.1.4 内排序的特点,待排序记录序列的存储结构:const int MAXSIZE=20/定义最大顺序表的长度typedef struct RcdType rMAXSIZE+1;/r0闲置或作为“哨兵”int length;/顺序表的真正长度SqList;/顺序表类型 内部排序的过程是一个逐步扩大记录的有

5、序序列的过程。通常在排序的过程中,参与排序的记录序列可划分两个区域:有序序列区和无序序列区,其中有序序列区的的记录已按关键字非递减有序排列。使有序序列中记录的数目至少增加一个的操作称为一趟排序。,选择排序法,思想:在排序过程序中,依次从待排序的记录序列中选择出关键字值最小的记录、关键字值次小的记录、,并分别有序序列中的第1个位置、第二个位置、,最后剩下一个关键字值最大的记录位于序列的最后一个位置,从而使待排序的记录序列成为按关键字值由小到大排列的的有序序列。,Rj,Ri,一趟排序后,一趟排序开始,3.1.5 选择排序法,一趟排序算法:void SelectPass(SqList/SelectP

6、ass,3.1.5 选择排序法,整个算法:void SelectSort(SqList/for/SelectSort,3.1.5 选择排序法,初始状态,i=1,i=2,i=3,i=4,i=5,i=6,i=7,3.1.5 选择排序法,时间复杂度:O(n2)空间复杂度:O(1)优点:算法简单;辅助空间少。缺点:效率低;不稳定性排序。,3.2 简单排序方法,3.2.1 插入排序3.2.2 起泡排序,3.2.1 插入排序,基本思想:依次将记录序列中的每一个记录插入到有序段中,使有序段的长度不断地扩大。其具体的排序过程可以描述如下:首先将待排序记录序列中的第一个记录作为一个有序段,将记录序列中的第二个记

7、录插入到上述有序段中,形成由两个记录组成的有序段,再将记录序列中的第三个记录插入到这个有序段中,形成由三个记录组成的有序段,依此类推,每一趟都是将一个记录插入到前面的有序段中。假设当前欲处理第i个记录,则将Ri这个记录插入到有序R1.i-1 段中,从而使有序序列长度增1,直到所有记录都插入到有序段中。一共需要经过n-1趟就可以将初始序列的n个记录重新排列成按关键字值大小排列的有序序列。,Ri,一趟排序后,一趟排序开始,3.2.1 插入排序,6,9,3,6,9,3,4,6,9,插入9,插入3,插入4,起始,3.2.1 插入排序,一趟排序算法:void InsertPass(SqList/插入到正

8、确位置/InsertPass,3.2.1 插入排序,整个算法:void InsertSort(SqList/插入到正确位置/InsertSort,3.2.1 插入排序,初始状态,i=2,i=3,i=4,i=5,i=6,i=7,i=8,3.2.1 插入排序,时间复杂度最佳状况(正序):O(n)最坏状况(逆序):O(n2)平均状况:O(n2)空间复杂度:O(1)优点:算法简单;稳定排序。缺点:花费较长的排序时间。,3.2.2 起泡排序,思想:通过对无序序列区中的记录进行相邻记录关键字间的“比较”和记录位置的“交换”实现关键字较小的记录向“一头”漂移,而关键字较大的记录向“另一头”下沉,从而达到记录

9、按关键字非递减顺序有序排列的目标。,i,一趟排序后,一趟排序开始,3.2.2 起泡排序,96,8,96,54,8,37,3.2.2 起泡排序,一趟排序算法:void BubblePass(SqList/if/for/BubblePass,3.2.2 起泡排序,整个算法:void BubbleSort(SqList/if/for/for/BubbleSort,3.2.2 起泡排序,改进的起泡算法:void BubbleSort(SqList/while/BubbleSort,3.2.2 起泡排序,初始状态,i=8,i=7,i=6,i=5,i=3,i=2,3.2.2 起泡排序,时间复杂度最佳状况:

10、O(n)最坏状况:O(n2)平均状况:O(n2)空间复杂度:O(1)优点:算法简单;空间效率高;结点顺序好效率就高;稳定的排序法。缺点:结点顺序不好则效率过低。,3.3 先进排序方法,3.3.1 快速排序3.3.2 归并排序3.3.3 堆排序(略),快速排序,基本思想:通过一趟排序将待排记录分割成相邻的两个区域,其中一个区域中记录的关键字均比另一个区域中记录的关键字小(区域内不一定有序),则可分别对这两个区域的记录进行再排序,以达到整个序列有序。假设将待排序的原始记录序列为(rs,rs+1,rt-1,rt),则一趟快速排序的基本操作是:任选一个记录(通常选rs),以他的关键字作为“枢轴”,凡序

11、列中关键字小于枢轴的记录均移动至该记录之前;反之,凡序列中关键字大于枢轴的记录均移动至该记录之后。致使一趟排序之后,记录的无序序列Rs.t将分割成两部分:Rs.i-1和Ri+1.t,且使 Rj.keyRi.key rj.key(s j i-1)枢轴(i+1j t),快速排序,一趟排序具体操作过程:假设枢轴记录的关键字为pivotkey,附设两个指针low和high,它们的初值分别为s和t。将枢轴记录复制到临时变量检测指针high所指记录若Rhigh.key=pivotkey,则减小high否则将Rhigh移至指针low所指位置检测指针所指记录若Rlow.key=pivotkey,则增加low否

12、则将Rlow移至指针high所指位置重复进行,直至low和high指向同一位置。,3.3.1 快速排序,17,14,65,28,36,3.3.1 快速排序,一趟排序算法:int Partition(RcdType R,int low,int high)int pivotkey;R0=Rlow;/将枢轴放在闲置单元 pivotkey=Rlow.key;/将枢轴的关键字放在pivotkey while(low=pivotkey)high-;/high往左找,比小时停止 if(lowhigh)Rlow+=Rhigh;/把比枢轴小的记录移到低端 while(lowhigh/返回枢轴位置/Partiti

13、on,3.3.1 快速排序,整个算法:void QSort(RcdType R,int s,int t)/对记录序列Rs.t进行快速排序 if(s1 pivotLoc=Partition(R,s,t);/对Rs.t进行一次划分 QSort(R,s,pivotLoc-1);/对低端子序列递归排序 QSort(R,s,pivotLoc-1);/对高端子序列递归排序/if/QSortvoid QuickSort(SqList/QuickSort,一趟快速排序示例,3.3.1 快速排序,初始状态,一次划分,3.3.1 快速排序,时间复杂度:最佳状况(当每次分割的两个区块都均匀大小时):O(n*log2

14、n)最坏状况(每次分割的两个区块大小相差很多时):O(n2)平均状况:O(n*log2n)空间复杂度:使用递归的深度最佳状况:O(log2n)最坏状况:O(n)平均状况:介于O(log2n)和O(n)之间优点:平均时间复杂度低,适用于完全随机的序列。缺点:不稳定性排序;空间效率低;结点顺序不好则效率低。,归并排序,归并排序法是利用“归并”操作的一种排序方法。基本思想:将待排序的原始记录序列Rs.t中取一个中间位置(s+t)/2,先分别对子序列Rs.(s+t)/2和R(s+t)/2+1.t进行递归的归并排序,然后进行一次归并处理。,3.3.2 归并排序,归并排序基本操作将两个位置相邻的有序记录子

15、序列Ri.m和Rm+1.n归并为一个有序记录序列Rn,算法如下:void Merge(RcdType SR,RcdType TR,int i,int m,int n)/对有序的Ri.m和Ri+1.n归并为一个有序的Rn for(j=m+1,k=i;i=m/将剩余的Rj.n复制到TR/Merge,3.3.2 归并排序,整个算法:void MSort(RcdType SR,RcdType TR1,int s,int t)/对记录序列Rs.t进行归并排序,排序后存入TR1s.t RcdType TR2t-s+1;/开设存放中间结果的辅助空间 if(s=t)TR1s=SRs;/递归出口 else m=

16、(s+t)/2;/将SRs.t平分为SRs.m和SRm+1.t MSort(SR,TR2,s,m);/递归地将SRs.m归并为TR2s.m MSort(SR,TR2,m+1,t);/递归地将SRm+1.t归并为TR2m+1.t Merge(TR2,TR1,s,m,t);/将TR2s.m和TR2m+1.t归并到TR1s.t/else/MSortvoid MergeSort(SqList/MergeSort,3.3.2 归并排序,2,3,1,4,3.3.2 归并排序,时间复杂度:O(n*log2n)空间复杂度:O(n)优点:可用来处理大量数据的排序;是稳定性排序。,3.3.3 堆排序,累堆的外观为

17、完全二叉树的根最小或最大树,而累堆排序所用的堆是“最大堆”(堆顶元素最大)。,父节点:Vi子节点:V2i(左)V2i+1(右),(2)将此二叉树建成最大堆,(1)将n个数存入数组,(3)取出树根,将剩下的节点在排成堆,(4)重复(3),直到所有值均以输出,3.3.3 堆排序,n=8-n/2=4,(1)考虑n4,n4 n8 不变,堆排序,(2)考虑n3,n3 n7 交换,堆排序,(3)考虑n2,n4n2n5n2 不变,3.3.3 堆排序,(4)考虑n1,n1 n2 交换,3.3.3 堆排序,考虑n2,n4 n2 交换,3.3.3 堆排序,考虑n4,n4n8 不变,最大堆,3.3.3 堆排序,取出

18、树根与最后一个节点交换,n1n8,n1n7成堆,3.3.3 堆排序,n1n7,n1n6成堆,3.3.3 堆排序,n1n6,n1n5成堆,3.3.3 堆排序,n1n5,n1n4成堆,3.3.3 堆排序,n1n4,n1n3成堆,3.3.3 堆排序,n1n3,n1n2成堆,3.3.3 堆排序,n1n2,void HeapSort(int*heap,int index)int i,j,temp;for(i=index/2;i=1;i-)createHeap(heap,i,index);for(i=index-1;i=1;i-)heap1heapi+1;/借助temp交换 createHeap(heap

19、,1,i);,void createHeap(int*heap,int root,int index)int i,j,temp,finish=0;j=2*root;temp=heaproot;while(j=heapj)finish=1;else heapj/2=heapj;j*=2;heapj/2=temp;,堆排序算法,调用HeapSort(list,index);,3.3.3 堆排序,时间复杂度:O(nlog2n)空间复杂度:O(1)优点:最坏情况下时间复杂度也仅为O(nlog2n)。缺点:运行时间主要耗费在建初始堆和调整堆上,排序数据较少时,不值得提倡。,3.4 基数排序,基本思想:基

20、数排序:假设记录的逻辑关键字由多个关键字构成,每个关键字可能取r个值,则只要从最低位关键字起,按关键字的不同值将记录“分配”到r个队列之后再“收集”在一起,如此重复趟,最终完成整个记录序列的排序。“基数”指的是r的取值范围。例:关键字为三位整数,其关键字构成是(k2,k1,k0),k2,k1,k0 的基数为10例:关键字为5个字母,其关键字构成是(k4,k3,k2,k1,k0),kj,(0收集-分配-收集,基数排序示例,3.4 基数排序,记录数组A,计数数组(个位),(a)初始状态和对“个位数”计数的结果,计数数组累加,记录数组B,30,63,83,74,94,25,05,78,18,09,8

21、9,69,(b)计数器的累加结果和记录“复制”后的状态,2,11,6,5,4,10,3,0,1,9,8,7,3.4 基数排序,(b)计数器的累加结果和记录“复制”后的状态,计数数组(十位),计数数组累加,记录数组A,05,09,18,25,30,63,69,74,78,83,89,94,(c)对“十位数”计数、累加和记录“复制”后的状态,记录数组B,6,10,1,2,8,0,3,11,7,9,5,4,3.4 基数排序,基数排序需说明的数据结构const int MAX_NUM_OF_KEY=6/关键字项数的最大值const int RADIX=10/关键字的基数const int MAXSIZ

22、E=10000 typedef struct KeysType keysMAX_NUM_OF_KEY;/关键字数组 InfoType otheritems;/其他数据项/int bitsnum;/关键字的位数RcdType;/基数排序中的记录类型,3.4 基数排序,一趟基数排序算法:void RadixPass(RcdType A,RcdType B,int n,int i)/对数组A中记录关键字的“第i位”计数,并累计count的值/将数组A中复制到数组B中 for(j=0;j=0;k-)/从右端开始复制记录 j=Ak.keysi;Bcountj-1=Ak;countj-;/for/Radi

23、xPass,3.4 基数排序,整个算法:void RadixSort(SqList/while/RadixSort,Typedef struct RcdType*r;int bitnum;int length;SqList,3.4 基数排序,时间复杂度:最佳状况、最坏状况、平均状况:O(d*n)空间复杂度:最佳状况、最坏状况、平均状况:O(n)优点:平均时间复杂度低;稳定性排序。缺点:空间效率低。,3.5 各种排序方法的综合比较,3.5.1 时间性能3.5.2 空间性能3.5.3 排序方法稳定性能3.5.4 小结,3.5.1 时间性能,按平均的时间性能来分,有三类排序方法:时间复杂度O(nlo

24、gn)的方法有:快速排序、堆排序和归并排序,其中快速排序目前被认为是最快的一种排序方法,后两者之比较,在n值较大的情况下,归并排序较堆排序更快。时间复杂度O(n2)的方法有:插入排序、起泡排序和选择排序,其中以插入排序为最常用,特别是已按关键字基本有序排列的记录序列尤为如此,选择排序过程中记录移动次数最少。当待排记录序列按关键字顺序有序时,插入排序和起泡排序能达到O(n)的时间复杂度;而对于快速排序而言,这是最不好的情况,此时的时间性能蜕化为O(n2)选择排序、堆排序和归并排序的时间性能不随记录序列中关键字的分布而改变,人们应事先对要排序的记录关键字的分布情况有所了解,才可1对症下药,选择有针

25、对性的排序方法。当待排序记录中其他各数据项比关键字占有更大的数据量时,还应考虑到排序过程中移动记录的操作时间,起泡排序效率最低。,3.5.2 空间性能,空间性能指的是排序过程中所需的辅助空间大小。所有的简单排序方法(包括:插入、起泡和选择排序)和堆排序的空间复杂度均为O(1).快速排序为O(logn),为递归程序执行过程中栈所需的辅助空间。归并排序和基数排序所需辅助空间最多,其空间复杂度为O(n)。,3.5.3 排序方法稳定性能,稳定的排序方法指的是对于两个关键字相等的记录在经过排之后,不改变它们在排序之前在序列中的相对位置。除快速排序和堆排序是不稳定的排序方法外,本章讨论的其他排序访方法都是

26、稳定的,例如,例如:对关键字序列(41,3,42,2)进行快速排序,其结果为(2,3,42,41)。“稳定性”是由方法本身决定的,一般来说,排序过程中所进行的比较操作和交换数据仅发生在相邻的记录之间,没有大步距的数据调整时,则排序方法是稳定的。,小结,3.5.4 小结,若待排序的记录个数n值较小(例如n30),则可选用插入排序法,若记录所含数据项较多,所占存储量大时,应选用选择排序法,反之,若待排序的记录个数n值较大时,应选用快速排序法,若待排序记录关键字有“有序”倾向时,就慎用快速排序,而宁可选用归并排序或堆排序。快速排序和归并排序在n值较小时的性能不及插入排序,可将它们和插入排序“混合”使

27、用,如在快速排序划分子区间的长度小于某值时,转而调用插入排序,或者对待排记录序列先逐段进行插入排序,然后再利用“归并操作”进行两两归并直至整个序列有序为止。基数排序的时间复杂度为O(d*n),因此特别适合于待排记录数n值很大,而关键字“位数d”较小的情况。并且还可以调整基数,减少基数排序的趟数。,3.6 谢耳排序法,基本思想:将欲排序的数值依某个间隔长度分成数个数列集合,再针对各个数列集合进行“插入法排序”,重复进行数列分割,每次分割的间割长度缩小为上一次分割间隔长度的二分之一,直到分割间隔为零停止,则数列排序完成。实例:,3.6 谢耳排序法,33,57,48,k=2,k=3,k=4,25,k

28、=5,k=6,k=7,92,57,37,k=1,k=2,33,25,k=3,k=4,k=5,k=6,k=7,void shellsort(Sqlist/while/shellsort,3.6 谢耳排序法算法,3.6 谢耳排序法,时间复杂度:O(nr)其中1r2空间复杂度:O(1)优点:以插入的方式进行排序,方法简易,由于插入排序法对已排序好的部分会快速处理,故最后几次程序速度会较快。,3.7 二叉树排序法,基本思想:将欲排序的元素一一以建立二叉树的方式插入;(1)每一个节点最多只有两个子节点(左节点、右节点)(2)若一节点有子节点,则该节点的数据要比左节点的数据大,且比右节点的数据小(左节点p

29、arent右节点)使用二叉树中序遍历的方式将二叉树的节点打输出来,即可得到元素的排序结果。实例:,3.7 二叉树排序法,算法:void binarytree(int*btree,int*list,int index)int i,level;btree1=list1;for(i=2;i=index;i+)level=1;while(btreelevel!=0)if(listibtreelevel level*=2;else level=2*level+1;btreelevel=listi;,3.7 二叉树排序法,时间复杂度:受高度影响,为 O(n*log2n)空间复杂度:O(n)优点:以插入的方式进行排序,方法简单。缺点:在插入节点时,第一个元素必为树根,若该值在数列中偏大或偏小,则会使树的歪斜程度加大,从而影响排序速度。稳定性:由排序条件决定左节点 parent 右节点,稳定排序左节点 parent 右节点,不稳定排序,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号