第九章内部排序
数据结构第九章排序习题与答案
习题九排序一、单项选择题1.下列内部排序算法中:A.快速排序 B.直接插入排序C. 二路归并排序D.简单选择排序E. 起泡排序F.堆排序(1)其比较次数与序列初态无关的算法是()(2)不稳定的排序算法是()(3)在初始序列已基本有序(除去n 个元素中的某 k 个元素后即呈有序, k<<n)的情况下,排序效率最高的算法是()(4)排序的平均时间复杂度为O(n?logn)的算法是()为 O(n?n) 的算法是()2.比较次数与排序的初始状态无关的排序方法是( )。
A.直接插入排序B.起泡排序C.快速排序D.简单选择排序3.对一组数据( 84, 47, 25, 15, 21)排序,数据的排列次序在排序的过程中的变化为(1) 84 47 25 15 21(2) 15 47 25 84 21(3) 15 21 25 84 47(4) 15 21 25 47 84则采用的排序是 ()。
A. 选择B.冒泡C.快速D.插入4.下列排序算法中 ( )排序在一趟结束后不一定能选出一个元素放在其最终位置上。
A. 选择B.冒泡C.归并D.堆5.一组记录的关键码为(46,79,56, 38,40, 84),则利用快速排序的方法,以第一个记录为基准得到的一次划分结果为()。
A. (38,40,46,56,79,84) B. (40,38,46,79,56,84)C. (40,38,46,56,79,84) D. (40,38,46,84,56,79)6.下列排序算法中,在待排序数据已有序时,花费时间反而最多的是()排序。
A.冒泡 B. 希尔C. 快速D. 堆7.就平均性能而言,目前最好的内排序方法是() 排序法。
A. 冒泡B.希尔插入C.交换D.快速8.下列排序算法中,占用辅助空间最多的是:()A. 归并排序B.快速排序C.希尔排序D.堆排序9.若用冒泡排序方法对序列 {10,14,26,29,41,52}从大到小排序,需进行()次比较。
数据结构第九章内部排序
举例
比较 移动 次数 次数
012345678
五趟
38 49 65 76 90 13 27 49 12345次 1234567次
1、直接插入排序法
方法 ⑵依次逐个将Ri(i=2,3,…,n)插入已有的按关键字值有序 的序列,并使插入完成后的序列仍按关键字值有序。
举例
比较 移动 次数 次数
012345678
值 间的比较,
(3+4+…+n+1)=1()n/-2 1)(n+4)/2
次元素的移动。
1、直接插入排序法
算法时间复杂度在最好时为O ,最坏时为O( ,并需可要见一素直个接元插入的排辅序助法存在储空待间排(。数n)据元素序列已基n本2)有 少或待排数据元素个数较 时效率较高。 序
1、直接插入排序法
举例
比较 移动 次数 次数
012345678
二趟
38 49 65 97 76 13 27 49 1次
1、直接插入排序法
方法 ⑵依次逐个将Ri(i=2,3,…,n)插入已有的按关键字值有序 的序列,并使插入完成后的序列仍按关键字值有序。
举例
比较 移动 次数 次数
012345678
三趟
38 49 65 97 76 13 27 49 1次
数据结构第九章内部排序
一、基本术语
排序 将n个性质相同的数据元素按关键字值从小到大或从大
到小排为有序序列。 内部排序
当待排数据元素的数量较少时,可将其一次全部调入内 存进行排序,即称内部排序。 外部排序
当待排数据元素的数量较大时,在排序过程中尚需对外 存进行访问,则称外部排序。
一、基本术语
1、直接插入排序法
数据结构教程 第九章 排序
9.2.3 希尔排序
3.算法
void ShellSort() { gap=n/2;//初次增量取序列元素个数n的一半为步长 while(gap>0) { for(i=gap+1;i<=n;i++) { j=i-gap; while(j>0) { if(r[j]>r[j+gap]) { x=r[j];r[j]=r[j+gap];r[j+gap]=x; j=j-gap; }//对子序列作直接插入排序 else j=0; } } gap=gap/2;}//每次减半,直至步长为1 上一页 }
上一页
下一页
9.3 快速排序法
9.3.2 快速排序
3【例9-5】对数据序列:70, 75, 69, 32, 88, 18, 16, 58进行快速排序如图9-3所示。 4.算法
void QuickSort(int low, int high)//递归形式的快速排序 { int pivotpos; if(low<high) { pivotpos=Partition(low,high); QuickSort(low,pivotpos-1);//对低子表递归排序 QucikSort(pivotpos+1,high);//对高子表递归排序 } }
9.2 插入排序
9.2.2 二分插入排序
3.算法
void BinsSort() { for(i=2;i<=n;i++) { r[0]=r[i];low=1;high=i-1;//将r[i]暂存到r[0] while(low<=high) //在r[low..high]中折半查找有序插入的位置 { m=(low+high)/2;//折半 if(r[0].key<r[m].key) high=m-1;//插入点在低半区 else low=m+1;//插入点在高半区 } for(j=i-1;j>high+1;--j) r[j+1]=r[j];//记录后移 r[high+1]r[0];//插入 } 上一页 下一页
数据结构之 内排序
i=3: 49大于08,不必调整; i=2: 25大于25*和16,也不必调整; i=1: 21小于25和49,要调整!
16
08
而且21还应当向下比较!!
37
中国水利水电出版社
38 物料管理
Data Structures: Chapter 9
2.堆排序
例:对刚才建好的大根堆进行排序:
1 1 08 21 6 08 3 4
27
24
12
28 物料管理
Data Structures: Chapter 9
9.3
选
择 排 序
直接选择排序示例:
index [ 0 ]
[1] i=2 [2] [3] [4]
中国水利水电出版社
6 10
SORTED U N S O R T E D
28
24
12
29 物料管理
Data Structures: Chapter 9
中国水利水电出版社
5
6 物料管理
Data Structures: Chapter 9
9.2
插 入 排 序
插入排序的数据类型定义如下:
typedef struct elemtype //待排序的数据记录类型
{
keytype key;
//数据记录的关键字
anytype otherelem; //数据记录中的其他成份
}datatype;
中国水利水电出版社
6
7 物料管理
Data Structures: Chapter 9
9.2
插 入 排 序
0 1 36 2 24 3 10 4
6
1. 直接插入排序
5 12
数据结构第9章 排序
R[3] 10
R[4] 60
R[5] 25
R[6] 30
R[7] 18 18 18 18
18 36 20
10 10 36
60 60 60
25 25 25
30 30 30
【算法】直接插入排序 void D_InsertSort(datatype R[ ], int n) { /*对排序表R[1]..R[n]进行直接插入排序,n是记录的 个数*/ for(i=2; i<=n; i++) if (R[i].key<R[i-1].key) {R[0]=R[i]; /*将R[i]插入R[1].. R[i-1]中, R[0]为监测哨*/ for(j=i-1; R[0].key<R[j].key; j--) R[j+1]=R[j]; /*后移记录*/ R[j+1]=R[0]; /*插入到合适位置*/ } }
空间性能:除排序表以外的内存占用情况。 时间性能:比较关键码的次数,数据移动的次数。 它们往往是排序表规模(n)的函数
6. 记录和排序表的数据结构
一般采用顺序结构存储排序表。 记录和排序表的类型定义如下: #define MAXNUM … /* MAXNUM 为足够大的数 typedef struct { keytype key; …… } datatype; datatype R[MAXNUM]; /*关键码字段*/ /*其它信息*/ /*记录类型*/ /*定义排序表的存储
第一趟排序结果,使得间隔为5的字表有序: P=3
29 7 41 30 11 39 50 76 41 13 10 0 80 78 86
子序列分别为:{29,30,50,13,78},{7,11,76,100,86}, {41,39,41,80}。第二趟排序结果: P=1
数据结构第9章 排序
数据结构第9章排序数据结构第9章排序第9章排名本章主要内容:1、插入类排序算法2、交换类排序算法3、选择类排序算法4、归并类排序算法5、基数类排序算法本章重点难点1、希尔排序2、快速排序3、堆排序4.合并排序9.1基本概念1.关键字可以标识数据元素的数据项。
如果一个数据项可以唯一地标识一个数据元素,那么它被称为主关键字;否则,它被称为次要关键字。
2.排序是把一组无序地数据元素按照关键字值递增(或递减)地重新排列。
如果排序依据的是主关键字,排序的结果将是唯一的。
3.排序算法的稳定性如果要排序的记录序列中多个数据元素的关键字值相同,且排序后这些数据元素的相对顺序保持不变,则称排序算法稳定,否则称为不稳定。
4.内部排序与外部排序根据在排序过程中待排序的所有数据元素是否全部被放置在内存中,可将排序方法分为内部排序和外部排序两大类。
内部排序是指在排序的整个过程中,待排序的所有数据元素全部被放置在内存中;外部排序是指由于待排序的数据元素个数太多,不能同时放置在内存,而需要将一部分数据元素放在内存中,另一部分放在外围设备上。
整个排序过程需要在内存和外存之间进行多次数据交换才能得到排序结果。
本章仅讨论常用的内部排序方法。
5.排序的基本方法内部排序主要有5种方法:插入、交换、选择、归并和基数。
6.排序算法的效率评估排序算法的效率主要有两点:第一,在一定数据量的情况下,算法执行所消耗的平均时间。
对于排序操作,时间主要用于关键字之间的比较和数据元素的移动。
因此,我们可以认为一个有效的排序算法应该是尽可能少的比较和数据元素移动;第二个是执行算法所需的辅助存储空间。
辅助存储空间是指在一定数据量的情况下,除了要排序的数据元素所占用的存储空间外,执行算法所需的存储空间。
理想的空间效率是,算法执行期间所需的辅助空间与要排序的数据量无关。
7.待排序记录序列的存储结构待排序记录序列可以用顺序存储结构和和链式存储结构表示。
在本章的讨论中(除基数排序外),我们将待排序的记录序列用顺序存储结构表示,即用一维数组实现。
ch9排序(冲突_STEVEN-PC_2006-08-25 17-11-16)
9.2 插入排序
基本思想:每步将一个待排序的对象,按其关键码大 小,插入到前面已经排好序的一组对象的适当位臵 上,直到对象全部插入为止。
简言之,边插入边排序,保证子序列中随时都是排好序的。
插入排序有多种具体实现算法: 9.2.1 直接插入排序 9.2.2 折半插入排序 9.2.3 希尔排序
希尔排序算法
void ShellSort(SqList &L,int dlta[],int t) { /* 按增量序列dlta[0..t-1]对顺序表L作希尔排序。*/ int k; for(k=0;k<t;++k) { ShellInsert(L,dlta[k]); /* 一趟增量为dlta[k]的插入排序 */ printf("第%d趟排序结果: ",k+1); print(L); } }
【3, 5, 6, 9, 11,13,27, 31】
例2:关键字序列T= (21,25,49,25*,16,08),
请写出直接插入排序的具体实现过程。 *表示后一个25
解:假设该序列已存入一维数组V[7]中,将V[0]作为缓冲或 暂存单元(Temp)。则程序执行过程为:
初态:
暂 49 25 25* 16 存 08 0
——若待排序记录都在内存中,称为内部排序; ——若待排序记录一部分在内存,一部分在外存,则称为外部 排序。 注:外部排序时,要将数据分批调入内存来排序,中间结果 还要及时放入外存,显然外部排序要复杂得多。 大多数排序算法都有两个基本的操作: (1)比较两个关键字的大小
(2)将记录从一个位置移动到另一个位置
2. 排序的目的是什么?
——便于查找!
3.排序算法的好坏如何衡量?
数据结构 第9章(内排序)
3. 将R[j+1]=R[0] 实现整个序列的排序。
North China Electric Power University
排序算法如下:
void insort(List r, int n) {//r为给定的表,其记录为r[i],i=0,1,…,n,x为暂存单元。 for (i=2; i<=n; i++) { r[0]=r[i]; //r[0]作为标志位 j=i-1; while (r[0].key<r[j].key) { r[j+1]=r[j]; j--; } //j从i-1至0,r[j].key与r[i].key进行比较 r[j+1]=r[0]; } }//insort
North China Electric Power University
例如:
第二趟希尔排序,设增量d = 3
第三趟希尔排序,设增量d = 1
North China Electric Power University
希尔排序的算法描述如下:
void ShellInsert (List r,int d) //本算法对直接插入算法作了以下修改: // 1. 前后记录位臵的增量是d,而不是1; // 2. r[0]只是暂存单元,不是哨兵。当j<=0时,插入位臵已找到。 for (i=2;i<= n ; i++) { { r[0]=r[i]; for(i=d+1;i<=n;i++) j=i-1; if ( r[i] < r[i-d]) //需将r[i]插入有序增量子表 while ( r[0].key<r[j].key) { r[0] = r[i]; //暂存在R[0] { r[j+1]=r[j]; j=i-d ; j=j-1; while ((j>0) and (r[0] < r[j])) } { r[j+d] = r[j]; //记录后移,查找插入位臵 r[j+1]=r[0]; j=j-d; } } r[j+d] = r[0];//插入 } }
《数据结构》第九章习题 参考答案
《数据结构》第九章习题参考答案一、判断题(在正确说法的题后括号中打“√”,错误说法的题后括号中打“×”)1、快速排序是一种稳定的排序方法。
(×)2、在任何情况下,归并排序都比简单插入排序快。
(×)3、当待排序的元素很大时,为了交换元素的位置,移动元素要占用较多的时间,这是影响时间复杂度的主要因素。
(√)4、内排序要求数据一定要以顺序方式存储。
(×)5、直接选择排序算法在最好情况下的时间复杂度为O(n)。
( ×)6、快速排序总比简单排序快。
( ×)二、单项选择题1.在已知待排序文件已基本有序的前提下,效率最高的排序方法是(A)。
A.直接插入排序B.直接选择排序C.快速排序D.归并排序2.下列排序方法中,哪一个是稳定的排序方法?(B)A.直接选择排序B.折半插入排序C.希尔排序D.快速排序3、比较次数与排序的初始状态无关的排序方法是( B)。
A.直接插入排序B.起泡排序(时间复杂度O(n2))C.快速排序D.简单选择排序4、对一组数据(84,47,25,15,21)排序,数据的排列次序在排序的过程中的变化为(1)84 47 25 15 21 (2)15 47 25 84 21 (3)15 21 25 84 47 (4)15 21 25 47 84 则采用的排序是( A)。
A. 选择B. 冒泡C. 快速D. 插入5、快速排序方法在(D)情况下最不利于发挥其长处。
A. 要排序的数据量太大B. 要排序的数据中含有多个相同值C. 要排序的数据个数为奇数D. 要排序的数据已基本有序6、用某种排序方法对线性表{25,84,21,47,15,27,68,35,20}进行排序,各趟排序结束时的结果为:(基准)20,21,15,25,84,27,68,35,47(25)15,20,21,25,47,27,68,35,84(左20右47)15,20,21,25,35,27,47,68,84(左35右68)15,20,21,25,27,35,47,68,84 ;则采用的排序方法为(C)。
第9章 内部排序
筛选过程示例见p243的图9.8所示。
筛选算法为:
void sift(RecordType r[], int k,int m) /* 假设r[k..m]是以r[k]为根的完全二叉树,且分别以r[2k]和r[2k+1] 为根的左、右子树为大根堆,调整r[k],使整个序列r[k..m]满足堆的性 质 */ {t= r[k] ; /* 暂存“根”记录r[k] */ x=r[k].key ;i=k ;j=2*i ;finished=FALSE ;
简单选择排序算法分析:
在简单选择排序过程中,所需移动记录的次数 比较少。最好情况下,即待排序记录初始状态就已 经是正序排列了,则不需要移动记录。最坏情况下, 即待排序记录初始状态是按逆序排列的,则需要移 动记录的次数最多为3(n-1)。
进行比较操作的时间复杂度为O(n2)。
9.4.2 树型选择排序
内部排序:整个排序过程完全在内存中进行,称为 内部排序。
外部排序:由于待排序记录数据量太大,内存无 法容纳全部数据,排序需要借助外部存储设备才 能完成,称为外部排序。
稳定排序和不稳定排序:假设Ki=Kj(1≤i≤n, 1≤j≤n,i≠j),若在排序前的序列中Ri领先于 Rj(即i<j),经过排序后得到的序列中Ri仍领先于Rj, 则称所用的排序方法是稳定的 ;反之,当相同关键 字的领先关系在排序过程中发生变化者,则称所用 的排序方法是不稳定的。
6
9
7
1
5
7
6
3
(a) 选 出 最 小
关键字13
2 7
2
4
7
9
232Fra bibliotek87
3 8
4
3
9
8
第9章_排序
比较次数的最大值 (n i) n(n 1) / 2 O(n2 ) i 1
n1
移动次数的最大值 3(n i) 3n(n 1) / 2 O(n2 ) i 1
冒泡排序方法是稳定的。
9.3.2 快速排序
快速排序的基本思想
快速排序方法是一种所需比较次数较少、在 内部排序中速度比较快的排序方法。
其思想是在待排序的记录序列中任取某个记 录(作为基准)的值作为控制值,采用某种 方法把这个记录放到适当的位置,使得这个 位置的左边的所有记录的值都小于或等于这 个控制值,而这个位置的右边的所有记录的 值都大于或等于这个控制值。
例9.4 (a) 一趟快速排序示例(一次划分过程)
49 38 65 97 76 13 27 49’
排序 所谓排序(Sort),就是要整理文件中的 记录,使它们按关键字递增(或递减)次序重新排 列。排序的确切定义为: 假设文件中有n个记录R1,R2,…Rn,其相应的 关键字分别为K1,K2,…Kn。所谓排序,是需要将 这Ki1n≤个Ki记2≤录…重≤K新in(排或列Ki为1 ≥RKi1i2,R≥i…2,…≥RKiinn,)使。得
例9.1 直接插入排序举例
[初始关键字]
i=2 (38) i=3 (65) i=4 (97) i=5 (76) i=6 (13) i=7 (27) i=8 (49)
监视哨R[0]
[49] 38 65 97 76 13 27 49
[38 49] 65 97 76 13 27 49 [38 49 65] 97 76 13 27 49 [38 49 65 97] 76 13 27 49 [38 49 65 76 97] 13 27 49 [13 38 49 65 76 97] 27 49 [13 27 38 49 65 76 97] 49 [13 27 38 49 49 65 76 97]
内 部 排 序
归并排序
将两个或多个有序表合并成一个有序表的过程。若将两个有 序表合并成一个有序表则称作二路归并,同理,有三路归并、 四路归并等。其中,二路归并最简单且常用。
在排序过程中,需要利用一个与待排序数组同样大小的数组 作为辅助。
首先把待排序区间中的每一个元素看成是一个有序表。则n 个元素构成n个有序表。接着两两归并,即第一个表和第二个 表归并,第三个表和第四个表归并,以此类推。
O(n2) O(n2) O(nlog2n) O(nlog2n) O(nlog2n) O(d(n+rd))
空间复杂度 O(1)
O(1) O(1) O(1) O(log2n) O(n) O(d(n+rd))
稳定性 稳定 不稳定 稳定 不稳定 不稳定 不稳定 稳定 稳定
数据结构
选择排序
简单选择排序
由若干个元素组成的序列中,选择一个关键字最大或 最小的元素输出,然后再从剩余的元素中选择一个关键 字最大或最小的元素输出。以此类推,直到排序结束。
堆排序
堆是一棵完全二叉树,其中任一非叶子结点的关键字 均大于(或小于)等于其孩子结点的关键字。它使用堆 结构来完成选择最小(最大)关键字的工作。
希尔排序
先将整个待排序元素分割成若干子序列分别进行排序, 待整个序列中的元素“基本有序”时,再对全体元素进行 一次直接插入排序。
希尔排序
交换排序
交换排序的基本思想是两两比较待排序对象,如果次序 与预期次序相反的话,则交换彼此的位置,直到所有对象 排好序为止。
冒泡排序
以升序为例,冒泡排序的基本思想是将集合中的元素逐 个进行比较,若第一个大于第二个,则交换两者的位置, 然后比较第二个元素和第三个元素的大小,依此类推,直 到全部元素比较完毕。
数据结构第九章 排序题库(40道)
数据结构第九章排序1、内排序方法中,从未排序序列中依次取出元素与已排序序列中的元素进行比较,将其放入已排序序列的正确位置上的方法,称为( )。
——[单选题]A 希尔排序B 冒泡排序C 直接插入排序D 简单选择排序正确答案:C2、对有n个记录的表进行直接插入排序,在最坏情况下需进行( )次关键字比较。
——[单选题]A n-1B n+1C n/2D n(n-1)/2正确答案:D3、在下列算法中,( )算法可能出现下列情况:在最后一趟开始之前,所有的元素都不在其最终的位置上。
——[单选题]A 堆排序B 冒泡排序C 直接插入排序D 快速排序正确答案:C4、对数据序列{15,9,7,8,20,-1,4}进行排序,进行一趟后数据的排序变为{9,15,7,8,20,-1,4},则采用的是( )算法。
——[单选题]A 简单选择排序B 冒泡排序C 直接插入排序D 堆排序正确答案:C5、数据序列{5,4,15,10,3,1,9,6,2}是某排序方法第一趟后的结果,该排序算法可能是( )。
——[单选题]A 冒泡排序B 二路归并排序C 堆排序D 简单选择排序正确答案:B6、从未排序序列中挑选元素,并将其依次插入已排序序列的一端的方法,称为( )。
——[单选题]A 希尔排序B 归并排序C 直接插入排序D 简单选择排序正确答案:D7、在以下排序方法中,关键字比较的次数与元素的初始排列次序无关的是( )。
——[单选题]A 希尔排序B 冒泡排序C 插入排序D 简单选择排序正确答案:D8、对n个不同的关键字进行递增冒泡排序,在下列哪种情况下比较的次数最多( )。
——[单选题]A 元素无序B 元素递增有序C 元素递减有序D 都一样正确答案:C9、对数据序列(8,9,10,4,5,6,20,1,2)进行递增排序,采用每趟冒出一个最小元素的冒泡排序算法,需要进行的趟数至少是( )。
——[单选题]A 3B 4C 5D 8正确答案:C10、为实现快速排序法,待排序序列最好采用的存储方式是( )。
数据结构第9章内部排序
算法步骤: (1)将整个待排序的记录序列划分成有序 区和无序区,初始时有序区为待排序记 录序列的第一个记录,无序区包括所有 剩余待排序的记录; (2)将无序区的第一个记录插入到有序 区的合适位置中,从而使无序区减少一 个记录,有序区增加一个记录; (3)重复执行(2),直到无序区中没有 记录为止。
希尔排序算法: void shell_sort(Sqlist *L, int dk[], int t)
/*按增量序列dk[0 … t-1],对顺序表L进行希尔排序*/
{ int m ; for (m=0; m<=t; m++) shell_pass(L, dk[m]) ; }
希尔排序可提高排序速度: (1) 分组后n值减小,n² 更小,而T(n)=O(n² ), 所以T(n)从总体上看减小了; (2) 关键字较小的记录可以以增量为单位跳 跃式前移,当进行最后一趟增量为1的插 入排序时,序列已基本有序。 增量序列取法: (1) 无除1以外的公因子; (2) 增量递减,最后一个增量值必须为1。
算法分析:
⑴ 最好情况:待排序记录按关键字从小到大排 列,算法中的内循环无须执行,每一趟排序时, 关键字比较1次,记录不需移动。所以整个排 序的关键字比较次数为n-1,记录移动次数为 0。 ⑵ 最坏情况:待排序记录按关键字从大到小排 列,每一趟排序时,算法中的内循环体执行i-1 次,关键字比较次数i次,记录移动次数i+1。 一般地,认为待排序的记录在各个位置的插入 概率相同,则取以上两种情况的平均值,作为 排序的关键字比较次数和记录移动次数,约为 n2/4,由此,直接插入排序的平均时间复杂度 为O(n2)。
插入排序
插入排序是一类借助“插入”操作进行 排序的方法,其主要思想是:每次将一 个待排序的记录按其关键字的大小插入 到一个已经排好序的有序序列中,直到 全部记录排好序。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
西南交通大学信息科学与技术学院软件工程系‐赵宏宇
数据结构A 第9章‐16
9.4 快速排序
1. 算法原理 快速排序(Quick Sort)是对冒泡排序的一种改进, 其原理如下。 设待排记录下标范围为R[s..t],任选一个记录称为 枢轴(或支点)(pivot),设法将枢轴通过移动和交换元素 的操作放置到排序后的正确位置R[i],然后对R[s..i-1] 和R[i+1..t]分别进行快速排序(递归思想)。 对排序范围R[s..t],将枢轴元素放置到正确位置的 操作称为一趟快排。 2. 枢轴元素的选取方法 (1) 选R[s]作为枢轴,操作比较方便 (2) “三者取中”法可明显改善时间复杂度
西南交通大学信息科学与技术学院软件工程系‐赵宏宇 数据结构A 第9章‐4
西南交通大学信息科学与技术学院软件工程系‐赵宏宇
数据结构A 第9章‐3
9.2 三种T(n)=O(n2)的内部排序
1. 简单选择排序 算法原理:基于1维数组元素选最大值/最小值 R[0..n-1]升序排列方法: (0) R[0..n-1]选出最小值元素和R[0]交换; (1) R[1..n-1]选出最小值元素和R[1]交换; … (i) R[i..n-1]选出最小值元素和R[i]交换; … (n-2) R[n-2..n-1]选出最小值和R[n-2]交换。
西南交通大学信息科学与技术学院软件工程系‐赵宏宇 数据结构A 第9章‐11
9.3 希尔排序
续1
对每个第s趟分割(s=0, 1, … , m-1),将全体待排元 素按下标的模ds剩余类分组(即元素下标模ds同余的分 在同一组),每组按下标递增次序进行直接插入排序。 如:排序下标范围R[0..9],ds=3,因模3的余数=0, 1, 2 故共分3组,即 模3余0:R[0], R[3], R[6], R[9] 模3余1:R[1], R[4], R[7] 模3余2:R[2], R[5], R[8] 显然,dm-1=1时,全体记录只分为一组,即最后一趟 进行一次普通直接插入排序。由于前面已进行了m-1 趟分组的插入排序,使整个序列接近正序,因此最后 一趟直接插入排序的效率较高。
西南交通大学信息科学与技术学院软件工程系‐赵宏宇
数据结构A 第8章‐2
9.1 内部排序的基本概念
续1
9.1 内部排序的基本概念
续2完
2. 排序的稳定性 当0i<jn-1时,若Ri.K=Rj.K,排序结束后必有Ri 排列在Rj之前,称排序为稳定的,否则为不稳定的。 排序稳定性的另一种等价定义形式为:排序结束 后,对任意i<j,若 R p .K R p .K,必有pi<pj。 i j 3. 内部与外部排序 内部排序:待排序数据元素全部在内存中存储。 外部排序:待排序数据元素数目太多,不能全部存于 内存中,排序过程必须从外存读写数据元素。 本章仅讨论内部排序算法。
西南交通大学信息科学与技术学院软件工程系‐赵宏宇 数据结构A 第9章‐17
9.4 快速排序
续1
所谓“三者取中”,是指比较R[s].K, R[(s+t)/2].K 和R[t].K三个元素的关键字,取中间大小元素作枢轴。 为方便操作,若枢轴不是R[s],将它先与R[s]交换,即 仍然选R[s]为枢轴。 //“三者取中”算法 m=(s+t)/2; //首先,使R[j1].K<R[j2].K if(R[m].K<R[t].K) { j1=m; j2=t; } else { j1=t; j2=m; } if(R[s].K<R[j1].K) swap(R[s],R[j1]); //R[j1].K为中间大小 else if(R[s].K>R[j2].K) swap(R[s],R[j2]); //R[j2].K为中间大小
续5完
西南交通大学信息科学与技术学院软件工程系‐赵宏宇
数据结构A 第9章‐9
西南交通大学信息科学与技术学院软件工程系‐赵宏宇
数据结构A 第9章‐10
9.3 希尔排序
1. 算法原理 希尔(Shell)排序的思想将整个待排记录序列分割 成为若干子序列,分别进行直接插入排序,待整个序 列中的记录“基本有序”时,再对全体记录进行一次 直接插入排序。 子序列的分割方法: 采用m个缩小增量d0, d1, …, dm-1实现分割,要求 (1) d 0 d1 d m 1 (2) d m 1 1 (3) gcd(d 0 , d1 , d m 1 ) 1 (gcd表示最大公约数)
西南交通大学信息科学与技术学院软件工程系‐赵宏宇
数据结构A 第9章‐13
西南交通大学信息科学与技术学院软件工程系‐赵宏宇
数据结构A 第9章‐14
9.3 希尔排序
续4
9.3 希尔排序
4. Shell排序算法的时间复杂度 (1) 增量序列取2.(1)时,T(n)=O(n1.5) (2) n在某个特定范围内,T(n)=O(n1.3) (3) n,T(n)=O(n(log2n)2) 5. Shell排序算法的稳定性 不一定稳定。
西南交通大学信息科学与技术学院软件工程系‐赵宏宇 数据结构A 第9章‐6
西南交通大学信息科学与技术学院软件工程系‐赵宏宇
数据结构A 第9章‐5
1
2014/12/16
9.2 三种T(n)=O(n2)的内部排序
续2
9.2 三种T(n)=O(n2)的内部排序
续3
2. 直接插入排序 算法原理:基于有序数组插入元素保持有序算法 R[0..n-1]升序排列方法: (1) R[0..0]升序, R[1]插入使R[0..1]升序排列; (2) R[0..1]升序, R[2]插入使R[0..2]升序排列; … (i) R[0..i-1]升序, R[i]插入使R[0..i]升序排列; … (n-1) R[0..n-2], R[n-1]插入使R[0..n-1]升序排列;
9.1 内部排序的基本概念
1. 什么是排序(sort)? 由n个数据元素(也称为数据对象或记录)组成的集 合{ R0, R1, … , Rn-1 },记Ri.K表示Ri的关键字K,需确 定下标集合{ 0, 1, … , n-1}的一个排列{ p0, p1, …, pn-1 }, 满足 R p0 .K R p1 .K R pn1 .K (n个元素按关键 字K非递减有序) 或 R p0 .K R p1 .K R pn1 .K (n个元素按关键 字K非递增有序) 这样一种操作称为排序或分类。
9.2 三种T(n)=O(n2)的内部排序
续1
void SelSort(ElemTp R[], int n) //非递归实现 { for(i=0; i<=n-2; i++) { m=i; for(j=i; j<n; j++) if(R[j].K<R[m].K) m=j; if(m!=i) swap(R[i], R[m]); } //用<为稳定的,用<=不稳定 } void SelSort1(ElemTp R[], int n, int i) //递归实现 { if(i>=n-2) return; m=i; for(j=i; j<n; j++) if(R[j].K<R[m].K) m=j; if(m!=i) swap(R[i], R[m]); SelSort1(R, n, i+1); }
西南交通大学信息科学与技术学院软件工程系‐赵宏宇 数据结构A 第9章‐12
2
2014/12/16
9.3 希尔排序
续2
9.3 希尔排序
续3
例 设递减增量序列为5, 3, 1, 对以下10元序列进行由小 到大希尔排序,写出各趟增量排序结果。 49 38 65 97 76 13 27 49 55 04 解:元素 49 38 65 97 76 13 27 49 55 04 第1趟 分组 0 1 2 3 4 0 1 2 3 4 增量=5 结果 13 27 49 55 04 49 38 65 97 76 第2趟 分组 0 1 2 0 1 2 0 1 2 0 增量=3 结果 13 04 49 38 27 49 55 65 97 76 第3趟 结果 04 13 27 38 49 49 55 65 76 97 增量=1
2. 增量的选取方法 (1) m log 2 ( n 1) 1, d s 2m s 1 (s 0,1,..., m 1) 例如,n=31, 则可取m=4,得4个递减的增量序列为: 15, 7, 3, 1 (2) m log 3 (2n 1), 1 d s 3m s 1 (s 0,1,..., m 1) 2 例如,n=31, 则可取m=3,得3个递减的增量序列为: 13, 4, 1
2014/12/16
第9章 内部排序
9.1 内部排序的基本概念 9.2 三种T(n)=O(n2)的内部排序 9.3 希尔排序 9.4 快速排序 9.5 堆排序 9.6 归并排序 9.7 基数排序 9.8 各种排序方法对比 第9章 作业
西南交通大学信息科学与技术学院软件工程系‐赵宏宇 数据结构A 第9章‐1
4. 待排序数据元素的存储结构 本章仅讨论数组顺序存储。其它存储结构也可以 实现数据元素的排序,如:二叉排序树(中序遍历得 数据元素的非递减有序序列),单链表数据元素按关 键字有序连接等。 5. 数组元素排序的主要操作 (1) 关键字比较大小; (2) 元素存储位置的移动。 为避免数据元素存储位置移动操作,排序结果可 以只生成下标集合的排列{ p0, p1, …, pn-1 }(只需要移 动下标数组p中的下标),而数据元素本身的存储位置 不需要移动,称为地址排序。
void InsertSort(ElemTp R[], int n) //非递归实现 { for(i=1; i<n; i++) { e=R[i]; key=R[i].K; for(j=i-1; j>=0&&R[j].K>key; j--) R[j+1]=R[j]; R[j+1]=e; //用>为稳定的,>=不稳定 } } 特点: a. 排序前不必知道所有记录,接收一个元素排序1次; b. 也适用于单链表结点有序连接; c. 初始序列“正序”时(各趟内循环次数均为0,即无 元素向后搬运),时间复杂度降低至O(n)