数据结构:第8章 排序1.ppt_第1页
数据结构:第8章 排序1.ppt_第2页
数据结构:第8章 排序1.ppt_第3页
数据结构:第8章 排序1.ppt_第4页
数据结构:第8章 排序1.ppt_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

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

文档简介

1、插入排序,交换排序,选择排序,其他排序算法 基数排序,各种排序方法的综合比较,第八章 排序,归并排序,一、什么是排序?,排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。,例如:将下列关键字序列,52, 49, 80, 36, 14, 58, 61, 23, 97, 75,调整为,14, 23, 36, 49, 52, 58, 61 ,75, 80, 97,排序的定义: 假设含n个记录的序列为 R1, R2, , Rn 其相应的关键字序列为 K1, K2, ,Kn ,这些关键字相互之间可以进行比较,即在 它们之间存在着这样一个关系 : Kp1Kp2Kp

2、n,按此固有关系将上式记录序列重新排列为 Rp1, Rp2, ,Rpn 的操作称作排序。,二、内部排序和外部排序,若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序;,反之,若参加排序的记录数量很大, 整个序列的排序过程不可能在内存中 完成,则称此类排序问题为外部排序。,按排序过程中依据的不同原则,内部排序方法大致可分下列几种类型:,插入排序,交换排序,选择排序,归并排序,其他排序,排序中使用的关键字Ki可以是主关键字,也可以是次关键字。 若Ki是次关键字,则排序结果不唯一,假设Ki=Kj( 1 i n, 1 j n, ij),且在排序前的序列中Ri领先于Rj(即ij)。 若在排

3、序后的序列中Ri仍领先于Rj;则称所用的排序方法是稳定的; 反之,若在排序后的序列中Rj领先于Ri;则称所用的排序方法是不稳定的,排序方法还可分为稳定的和不稳定的,插入排序,将无序子序列中的 记录逐个“插入”到有序序列中,从而增加记录的有序子序列的长度。,有序序列R1.i-1,Ri,无序序列 Ri.n,一趟直接插入排序的基本思想:,有序序列R1.i,无序序列 Ri+1.n,待排记录的数据类型定义如下:,#define MAXSIZE 1000 / 待排顺序表最大长度,typedef int KeyType; / 关键字类型为整数类型,typedef struct KeyType key; /

4、关键字项 OtherType other_data; / 其它数据项 RecordType; / 记录类型,RecordType RMAXSIZE+1 / 记录数组,实现“一趟插入排序”可分三步进行:,3将Ri 插入(复制)到Rj+1的位置上。,2将Rj+1.i-1中的所有记录均后移 一个位置;,1在R1.i-1中查找Ri的插入位置, R1.j.key Ri.key Rj+1.i-1.key;,直接插入排序(基于顺序查找),不同的具体实现方法导致不同的算法描述,折半插入排序(基于折半查找),希尔排序(基于逐趟缩小增量),一、直接插入排序,利用 “顺序查找”实现 “在R1.i-1中查找Ri的插入

5、位置”,从Ri-1起向前进行顺序查找, 监视哨设置在R0;,R0 = Ri; / 设置“哨兵”,循环结束表明Ri的插入位置为 j +1,R0,j,Ri,for (j=i-1; R0.keyRj.key; -j); / 从后往前找,j=i-1,插入位置,对于在查找过程中找到的那些关键字大于Ri.key的记录,可在查找的同时实现记录向后移动;,for (j=i-1; R0.keyRj.key; -j) Rj+1 = Rj,R0,j,Ri,j= i-1,上述循环结束后可以直接进行“插入”,插入位置,令 i = 2,3,, n, 实现整个序列的排序。,for ( i=2; i=n; +i ) if (

6、Ri.keyRi-1.key) R0=Ri; for(j=i-1;Ri.keyrj.key;j-) Rj+1 = Rj; Rj+1=R0; ,能改为“=”吗?,稳定吗?,Ri=Ri-1;,i-2,内部排序的时间分析:,实现内部排序的基本操作有两个:,(2)“移动”记录。,(1)“比较” 关键字;,对于直接插入排序:,最好的情况(关键字在记录序列中顺序有序):,“比较”的次数:,最坏的情况(关键字在记录序列中逆序有序):,“比较”的次数:,0,“移动”的次数:,“移动”的次数:,直接插入排序的时间复杂度为O(n2),因为 R1.i-1 是一个按关键字有序的序列,则可以利用折半查找实现“在R1.i

7、-1中查找Ri的插入位置”,如此实现的插入排序为折半插入排序。,二、折半插入排序,折半插入排序,for ( i=2; i=low;j-) Rj+1 = Rj; Rlow=R0; ,三、希尔排序(缩小增量排序),基本思想:对待排记录序列先作“宏观”调整,再作“微观”调整。,所谓“宏观”调整,指的是,“跳跃式” 的插入排序。 具体做法为:,将记录序列分成若干子序列,分别对每个子序列进行插入排序。,其中,d 称为增量,它的值在排序过程中从大到小逐渐缩小,直至最后一趟排序减为 1。,例如:将 n 个记录分成 d 个子序列: R1,R1+d,R1+2d,R1+kd R2,R2+d,R2+2d,R2+kd

8、 Rd,R2d,R3d,Rkd,R(k+1)d ,例如:,16 25 12 30 47 11 23 36 9 18 31,第一趟希尔排序,设增量 d =5,11 23 12 9 18 16 25 36 30 47 31,第二趟希尔排序,设增量 d = 3,9 18 12 11 23 16 25 31 30 47 36,第三趟希尔排序,设增量 d = 1,9 11 12 16 18 23 25 30 31 36 47,1 2 3 4 5 6 7 8 9 10 11,1 2 3 4 5 6 7 8 9 10 11,1 2 3 4 5 6 7 8 9 10 11,1 2 3 4 5 6 7 8 9

9、10 11,void ShellSort(RecordType a,int n,int d,int numOfD) /d数组存放预先设定的增量值序列, / numOfD为增量个数 int i,j,k,m,span; RecordType temp; for(m=0;mnumofD;m+) /共numOfD次循环 span=dm;/取本次的增量值 for(k=1;k=span;k+) /共span个小组 /对每个小组进行增量为span的直接插入排序 ,/对每个小组进行增量为span的直接插入排序 for(i=k+span;i0 / 插入到正确位置 ,交换排序,通过“交换”无序序列中的记录从而得到

10、其中关键字最小或最大的记录,并将它加入到有序子序列中,以此方法增加记录的有序子序列的长度。,一、冒泡排序,二、快速排序,交 换 排 序,一、冒泡排序,假设在排序过程中,记录序列R1.n的状态为:,第 i 趟冒泡排序,无序序列R1.n-i+1,有序序列 Rn-i+2.n,n-i+1,无序序列R1.n-i,有序序列 Rn-i+1.n,比较相邻记录,将关键字最大的记录交换到 n-i+1 的位置上,void BubbleSort1(RecordType a,int n) int i,j; RecordType temp; for(i=n; i1; i-) for(j=1; jaj+1.key) tem

11、p=aj; aj=aj+1; aj+1=temp; ,注意1:,冒泡排序的结束条件为: 某一趟冒泡没有进行“交换记录”。,void BubbleSort2(RecordType a,int n) int i,j,flag=1; RecordType temp; for(i=n; i1 ,注意2:,一般情况下,每经过一趟“冒泡”, “i 减一”,但并不是每趟都如此。,例如:,2,5,5,3,1,5,7,9,8,9,i=7,i=6,for (j = 1; j i; j+) if (Rj+1.key Rj.key) ,1,3,i=2,void bubblesort3(RecordType a,int

12、 n) int i, j, p, flag=1; RecordType temp; for(i=n; i1 ,p=1;,void bubblesort (RecordType a,int n) int i, j, p; RecordType temp; for(i=n; i1; i=p) p=1; for(j=1;jaj+1.key) temp=aj; aj=aj+1; aj+1=temp; p=j; ,冒泡排序时间分析:,最好的情况(关键字在记录序列中顺序有序): 只需进行一趟起泡,“比较”的次数:,最坏的情况(关键字在记录序列中逆序有序): 需进行n-1趟起泡,“比较”的次数:,0,“移动

13、”的次数:,“移动”的次数:,n-1,二、快速排序,首先根据某一控制记录(枢轴)对无序的记录序列进行“一次划分”,得到两个无序的子序列;之后分别对分割所得两个子序列“递归”进行快速排序。,无 序 的 记 录 序 列,无序记录子序列(1),无序子序列(2),枢轴,一次划分,分别进行快速排序,s,t,low,high,设 Rs=52 为枢轴,将 Rhigh.key 和 枢轴的关键字进行比较,要求Rhigh.key 枢轴的关键字,将 Rlow.key 和 枢轴的关键字进行比较,要求Rlow.key 枢轴的关键字,high,23,low,80,high,14,low,52,例如,R0,52,low,h

14、igh,high,high,low,一趟快速排序,可见,经过“一次划分” ,将关键字序列 52, 49, 80, 36, 14, 58, 61, 97, 23, 75 调整为: 23, 49, 14, 36, (52) 58, 61, 97, 80, 75,在调整过程中,设立了两个指针: low 和high,它们的初值分别为: s 和 t,,之后逐渐减小 high,增加 low,并保证 Rhigh.key52,和 Rlow.key52,否则进行记录的“交换”。 直至i=j;完成一趟快速排序。,void QuickSort(RecordType a,int low,int high) int i=low,j=high; a0=alow; /设置枢轴记录 while(ij) while(ij ,快速排序的时间分析,假设一次划分所得枢轴位置 i=k,则对n 个记录进行快排所需时间:,其中 Tpass(n)为对 n 个记录进行一次划分所需时间。,若待排序列中记录的关键字是随机分布的,则 k 取 1 至 n 中任意一值的可能性相同。,T(n) = Tpass(

温馨提示

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

评论

0/150

提交评论