《数据结构03排序》PPT课件.ppt_第1页
《数据结构03排序》PPT课件.ppt_第2页
《数据结构03排序》PPT课件.ppt_第3页
《数据结构03排序》PPT课件.ppt_第4页
《数据结构03排序》PPT课件.ppt_第5页
已阅读5页,还剩75页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

,数 据 结 构 (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 排序的分类 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 排序的特性稳定性与不稳定性 当待排记录中的关键字ki(1,2,n)都不相同时,则任何一个记录的无序序列经排序后得到的结果是惟一的。 简单地说,稳定性排序-数据排序过后能使值相同的数据,保持原顺序中之相对位置。反之,则称为“不稳定性排序” 。 若排序的序列中存在两个或两个以上关键字相等的记录时,则排序得到的记录序列的结果不惟一。 假设ki= kj (1i n, 1jn, ij ),且在排序前的序列中 ri 领先于rj (即ij ) 。若在排序后的序列中ri 总是领先于rj ,则称所用的排序方法是稳定的;反之,若可能使排序后的序列中 rj领先于ri ,则称所用的排序方法是不稳定的。,3.1.2 排序的特性稳定性与不稳定性,3.1.3 排序的分类,根据在排序的过程涉及的存储器不同,排序方法可分为两类: 1.内部排序(Internal Sort):在排序进行的过程中不使用计算机外部存储器的排序过程。 选择排序 插入排序 起泡排序 快速排序 归并排序 堆排序 基数排序 2. 外部排序(External Sort):在排序进行的过程中需要对外存进行访问的排序过程。,3.1.4 内排序的特点,待排序记录序列的存储结构: const int MAXSIZE=20 /定义最大顺序表的长度 typedef struct RcdType rMAXSIZE+1;/r0闲置或作为“哨兵” int length; /顺序表的真正长度 SqList; /顺序表类型 内部排序的过程是一个逐步扩大记录的有序序列的过程。通常在排序的过程中,参与排序的记录序列可划分两个区域:有序序列区和无序序列区,其中有序序列区的的记录已按关键字非递减有序排列。 使有序序列中记录的数目至少增加一个的操作称为一趟排序。,3.1.5 选择排序法,思想:在排序过程序中,依次从待排序的记录序列中选择出关键字值最小的记录、关键字值次小的记录、,并分别有序序列中的第1个位置、第二个位置、,最后剩下一个关键字值最大的记录位于序列的最后一个位置,从而使待排序的记录序列成为按关键字值由小到大排列的的有序序列。,Rj,Ri,一趟排序后,一趟排序开始,3.1.5 选择排序法,一趟排序算法: void SelectPass(SqList / SelectPass,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 插入排序,基本思想:依次将记录序列中的每一个记录插入到有序段中,使有序段的长度不断地扩大。其具体的排序过程可以描述如下:首先将待排序记录序列中的第一个记录作为一个有序段,将记录序列中的第二个记录插入到上述有序段中,形成由两个记录组成的有序段,再将记录序列中的第三个记录插入到这个有序段中,形成由三个记录组成的有序段,依此类推,每一趟都是将一个记录插入到前面的有序段中。 假设当前欲处理第i个记录,则将Ri这个记录插入到有序R1i-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 /插入到正确位置 /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 起泡排序,思想:通过对无序序列区中的记录进行相邻记录关键字间的“比较”和记录位置的“交换”实现关键字较小的记录向“一头”漂移,而关键字较大的记录向“另一头”下沉,从而达到记录按关键字非递减顺序有序排列的目标。,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 起泡排序,时间复杂度 最佳状况:O(n) 最坏状况:O(n2) 平均状况:O(n2) 空间复杂度: O(1) 优点: 算法简单;空间效率高;结点顺序好效率就高;稳定的排序法。 缺点: 结点顺序不好则效率过低。,3.3 先进排序方法,3.3.1 快速排序 3.3.2 归并排序 3.3.3 堆排序(略),3.3.1 快速排序,基本思想: 通过一趟排序将待排记录分割成相邻的两个区域,其中一个区域中记录的关键字均比另一个区域中记录的关键字小(区域内不一定有序),则可分别对这两个区域的记录进行再排序,以达到整个序列有序。 假设将待排序的原始记录序列为(rs, rs+1, rt-1,rt),则一趟快速排序的基本操作是:任选一个记录(通常选rs ),以他的关键字作为“枢轴”,凡序列中关键字小于枢轴的记录均移动至该记录之前;反之,凡序列中关键字大于枢轴的记录均移动至该记录之后。致使一趟排序之后,记录的无序序列Rst将分割成两部分:Rsi-1和Ri+1t,且使 Rj.keyRi.key rj.key (s j i-1) 枢轴 (i +1j t),3.3.1 快速排序,一趟排序具体操作过程:假设枢轴记录的关键字为pivotkey,附设两个指针low和high,它们的初值分别为s和t。 将枢轴记录复制到临时变量 检测指针high所指记录 若Rhigh.key=pivotkey,则减小high 否则将Rhigh移至指针low所指位置 检测指针所指记录 若Rlow.key=pivotkey,则增加low 否则将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 /返回枢轴位置 /Partition,3.3.1 快速排序,整个算法: void QSort(RcdType R,int s,int t) /对记录序列Rst进行快速排序 if(s1 pivotLoc=Partition(R,s,t); /对Rst进行一次划分 QSort(R,s,pivotLoc-1); /对低端子序列递归排序 QSort(R,s,pivotLoc-1); /对高端子序列递归排序 /if /QSort void QuickSort(SqList /QuickSort,一趟快速排序示例,3.3.1 快速排序,初始状态,一次划分,3.3.1 快速排序,时间复杂度: 最佳状况(当每次分割的两个区块都均匀大小时):O(n*log2n) 最坏状况(每次分割的两个区块大小相差很多时):O(n2) 平均状况: O(n*log2n) 空间复杂度:使用递归的深度 最佳状况: O(log2n) 最坏状况: O(n) 平均状况:介于O(log2n) 和O(n)之间 优点: 平均时间复杂度低,适用于完全随机的序列。 缺点: 不稳定性排序;空间效率低;结点顺序不好则效率低。,3.3.2 归并排序,归并排序法是利用“归并”操作的一种排序方法。 基本思想: 将待排序的原始记录序列Rst中取一个中间位置(s+t)/2,先分别对子序列Rs(s+t)/2和R(s+t)/2+1 t进行递归的归并排序,然后进行一次归并处理。,3.3.2 归并排序,归并排序基本操作将两个位置相邻的有序记录子序列Rim和Rm+1n归并为一个有序记录序列Rn,算法如下: void Merge(RcdType SR,RcdType TR,int i,int m,int n) /对有序的Rim和Ri+1n归并为一个有序的Rn for(j=m+1,k=i;i=m /将剩余的Rjn复制到TR /Merge,3.3.2 归并排序,整个算法: void MSort(RcdType SR,RcdType TR1, int s,int t) /对记录序列Rst进行归并排序,排序后存入TR1st RcdType TR2t-s+1; /开设存放中间结果的辅助空间 if(s=t) TR1s=SRs;/递归出口 else m=(s+t)/2; /将SRst平分为SRsm和SRm+1t MSort(SR,TR2,s,m); /递归地将SRsm归并为TR2sm MSort(SR,TR2,m+1,t); /递归地将SRm+1t归并为TR2m+1t Merge(TR2,TR1,s,m,t); /将TR2sm和TR2m+1t归并到TR1st /else /MSort void MergeSort(SqList /MergeSort,3.3.2 归并排序,2,3,1,4,3.3.2 归并排序,时间复杂度:O(n*log2n) 空间复杂度:O(n) 优点: 可用来处理大量数据的排序; 是稳定性排序。,3.3.3 堆排序,累堆的外观为完全二叉树的根最小或最大树,而累堆排序所用的堆是“最大堆”(堆顶元素最大)。,父节点: Vi 子节点: V2i (左) V2i+1 (右),(2) 将此二叉树建成最大堆,(1) 将n个数存入数组,(3) 取出树根,将剩下的节点在排成堆,(4) 重复(3),直到所有值均以输出,3.3.3 堆排序,n=8n/2=4,(1)考虑n4,n4 n8 不变,3.3.3 堆排序,(2)考虑n3,n3 n7 交换,3.3.3 堆排序,(3)考虑n2,n4n2 n5n2 不变,3.3.3 堆排序,(4)考虑n1,n1 n2 交换,3.3.3 堆排序,考虑n2,n4 n2 交换,3.3.3 堆排序,考虑n4,n4n8 不变,最大堆,3.3.3 堆排序,取出树根与最后一个节点交换,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,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 基数排序,基本思想: 基数排序:假设记录的逻辑关键字由多个关键字构成,每个关键字可能取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,89,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 MAXSIZE=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 /RadixPass,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(nlogn)的方法有:快速排序、堆排序和归并排序,其中快速排序目前被认为是最快的一种排序方法,后两者之比较,在n值较大的情况下,归并排序较堆排序更快。 时间复杂度O(n2 )的方法有:插入排序、起泡排序和选择排序,其中以插入排序为最常用,特别是已按关键字基本有序排列的记录序列尤为如此,选择排序过程中记录移动次数最少。 当待排记录序列按关键字顺序有序时,插入排序和起泡排序能达到O(n)的时间复杂度;而对于快速排序而言,这是最不好的情况,此时的时间性能蜕化为O(n2) 选择排序、堆排序和归并排序的时间性能不随记录序列中关键字的分布而改变,人们应事先对要排序的记录关键字的分布情况有所了解,才可1对症下药,选择有针对性的排序方法。 当待排序记录中其他各数据项比关键字占有更大的数据量时,还应考虑到排序过程中移动记录的操作时间,起泡排序效率最低。,3.5.2 空间性能,空间性能指的是排序过程中所需的辅助空间大小。 所有的简单排序方法(包括:插入、起泡和选择排序)和堆排序的空间复杂度均为O(1). 快速排序为O(logn),为递归程序执行过程中栈所需的辅助空间。 归并排序和基数排序所需辅助空间最多,其空间复杂度为O(n)。,3.5.3 排序方法稳定性能,稳定的排序方法指的是对于两个关键字相等的记录在经过排之后,不改变它们在排序之前在序列中的相对位置。 除快速排序和堆排序是不稳定的排序方法外,本章讨论的其他排序访方法都是稳定的,例如, 例如:对关键字序列(41,3,42,2)进行快速排序,其结果为(2,3,42,41)。 “稳定性”是由方法本身决定的,一般来说,排序过程中所进行的比较操作和交换数据仅发生在相邻的记录之间,没有大步距的数据调整时,则排序方法是稳定的。,3.5.4 小结,3.5.4 小结,若待排序的记录个数n值较小(例如n30),则可选用插入排序法,若记录所含数据项较多,所占存储量大时,应选用选择排序法,反之,若待排序的记录个数n值较大时,应选用快速排序法,若待排序记录关键字有“有序”倾向时,就慎用快速排序,而宁可选用归并排序或堆排序。 快速排序和归并排序在n值较小时的性能不及插入排序,可将它们和插入排序“混合”使用,如在快速排序划分子区间的长度小于某值时,转而调用插入排序,或者对待排记录序列先逐段进行插入排序,然后再利用“归并操作”进行两两归并直至整个序列有序为止。 基数排序的时间复杂度为O(d*n),因此特别适合于待排记录数n值很大,而关键字“位数d”较小的情况。并且还可以

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论