第十章 排序
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一趟直接插入 排序
2.直接插入的算法实现
void InsertSort(SqList &L) { //对顺序表L作直接插入排序。
for (i=2; i<=L. length; ++i){
if LT(L.r[i].key, L.r[i-1].key){
//若L.r[i].key < L.r[i-1].key,需将L.r[i]插入有序子表,
1. 基本概念
1).排序码(Sort Key)
作为排序依据的记录中的一个属性。它可以是任何一种可比 的有序数据类型,它可以是记录的关键字,也可以是任何非关 键字。
2).有序表与无序表
一组记录按排序码的递增或递减次序排列得到的结果被称 之为有序表,相应地,把排序前的状态称为无序表。
3).正序表与逆序表
3)适用于n 较大情况
10.3 快速(交换)排序
将待排记录中两两记录关键字进行比较,若逆序则交换位置。
例:49 38 65 97 76 13 27 49 若按关键字递增的顺序排序,则 49 38 为逆序
不同的比较顺序就得到不同的交换排序方法
10.3.1起泡排序
1.起泡排序(Bubble Sorting)的基本思想是:是通过对待 排序序列从后向前(从下标较大的元素开始),依次比较相邻元素 的排序码,若发现逆序则交换,使排序码较小的元素逐渐从后部移 向前部(从下标较大的单元移向下标较小的单元),就象水底下的 气泡一样逐渐向上冒。
10
M 49 38 65 97 76 13 27 49’ 2 01
2)算法实现 见P270 算法10.3 是将排好序的静态链表按指针顺序进行记录调整
3)性能分析 从算法可见,表插入排序的基本操作仍是将一个记录插入到已排
好序的有序表中,不同之处仅在于以修改2n次指针代替移动记录, 关键字比较次数相同,时间复杂度仍是O(n2)
ຫໍສະໝຸດ Baidu
int length;
//顺序表长度
}SqList;
//顺序表类型
排序
插入排序(直插排序、二分排序、表插入排序、 希尔排序) 交换排序(冒泡排序、快速排序)
选择排序 (直选排序、树型排序、堆排序)
10.2 插入排序
10.2.1 直接插入排序
1.基本思想 直接插入排序(Straight Insertion Sorting)的基本思
typedef int KeyType; //定义关键字类型为整数类型
typedef struct{
KeyType key;
//关键字项
InfoType otherinfo; //其它数据项
}RedType;
//记录类型
typedef struct{
RedType r[MAXSIZE+1]; //r[0]闲置或用作哨兵单元
二分插入算法与直接插入算法的元素移动一样是顺序的,因此该 方法也是稳定的。
2.表插入排序 1)基本思想 记录放在静态链表中,进行插入排序,可以不移动元素。
#define SIZE 100 Typedef struct{
RcdType rc; int next; }SLNode; Typedef struct{ SLNode r[SIZE]; int length; }SLinkListType;
(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)
7).排序的时间复杂性
排序过程主要是对记录的排序码进行比较和记录的移动过程。 因此排序的时间复杂性可以算法执行中的数据比较次数及数据移 动次数来衡量。当一种排序方法使排序过程在最坏或平均情况下 所进行的比较和移动次数越少,则认为该方法的时间复杂性就越 好,分析一种排序方法,不仅要分析它的时间复杂性,而且要分 析它的空间复杂性、稳定性和简单性等。
以上述说明的静态链表作为存储结构,为了插入方便,设数组中下 标为0的分量为表头结点,并令表头结点记录的关键字取最大整数 MAXINT。则表插入排序如下:首先将静态链表中数组下标为1的分量 与表头结点构成一个循环链表,然后依次将下标为2到n的记录插入到 循环链表中。
012345678 M 49 38 65 97 76 13 27 49’
76 38 49 65 97 97 13 27 49
0 1 23 4 5 67 8 9
76 38 49 65 9776 97 13 27 49
3.直接插入排序的效率分析
从算法可以看出,直接插入排序算法十分简单。那么它的效率如何 呢?首先从空间来看,它只需要一个元素的辅助空间,用于元素的位 置交换。
若有序表是按排序码升序排列的,则称为升序表或正序表, 否则称为降序表或逆序表。不失普遍性,我们一般只讨论正序表。
4). 排序定义
若给定一组记录的文件{r1 ,r2 ,…,rn},其相应的排序码分 别为{k1,k2 ,…,kn },需确定一种排列p1 , p2 , … pn ,以使排 序码的序列满足: kp1 ≤ kp2 ≤ … ≤kpn即使上述文件成为按排序码 线性有序 {rp1 ,rp2 ,…,rpn },这一过程称为排序。 也可以说,将一组记录按某排序码递增或递减排列的过程,称为 排序。
第十章 内部排序
10.1 概述 10.2 插入排序 10.3 快速排序 10.4 选择排序
学习要点 1 理解排序的定义和各种排序方法的特点; 2 了解各种方法的排序过程及其依据的原则; 3 理解“稳定”或“不稳定”的含义;
10.1 概 述
排序(Sorting)是数据处理中一种很重要的运算,同时 也是很常用的运算,一般数据处理工作25%的时间都在进行排 序。简单地说,排序就是把一组记录(元素)按照某个域的值 的递增(即由小到大)或递减(即由大到小)的次序重新排列 的过程。
L.r[5]复制为哨兵
76 38 49 65 97 76 13 27 49
0 1 23 4 5 6 78 9
76 38 49 65 97 97 13 27 49
L.r[0].key < L.r[4].key , L.r[4]记录后移
L.r[0].key L.r[3].key
找到插入位置
插入!
0 1 23 4 5 67 8 9
L.r[0]=L.r[i];
// L.r[i]复制为哨兵
for(j=i-1; LT(L.r(0).key, L.r[j].key); --j ) //从后向前查找子表
L.r[j+1]=L.r[j];
// 若L.r[i].key < L.r[j].key, L.r[j]记录后移
L.r[j+1]=L.r[0]; //插入到正确位置
Donald L. Shell 博士(1924- )在计算机科学领域的贡献是 ShellSort 。 1984 年退休。
1951年获取硕士学位, 1959 年博士学位。
希尔在1959年针对插入排序作了改进,提出了一个缩小增量排 序方法。 方法:先取一个正整数d1<n,把所有相隔d1的数据作为一组,组 内进行直接插入排序;然后取d2<d1,重复上述分组和排序操作; 直至di=1。
三趟排序: 4 13 27 38 48 49 55 65 76 97
2.希尔排序的算法实现 见P272 算法10.4,10.5
3.希尔排序的性能分析 希尔排序的性能分析是一个复杂的问题,是所取增量的函
数。 希尔排序的时间复杂性在O(nlog2n)和O(n2 )之间, 大致为O(n1. 3)。
特点 1)时间复杂度,取决于增量序列的选择,选择的好,效率优 于直接插入排序,其时间复杂度为0(nlog2n) 2)不稳定排序方法
二分查找的方法查找待排元素的插入位置。
其处理过程:先将第一个元素作为有序序列,进行n-1次插入,用二分 查找的方法查找待排元素的插入位置,将待排元素插入。
2).算法实现 见P267 算法10.2
3).效率分析
二分插入算法与直接插入算法相比,需要辅助空间与直接插 入排序基本一致;时间上,前者的比较次数比直接插入查找的最 坏情况好,最好的情况下,两种方法的元素的移动次数相同,因 此二分插入排序的时间复杂度仍为O(n2)。
10.2.3 希尔排序 1.希尔排序的基本思想
希尔排序(Shell Sort)又称为“缩小增量排序”。是1959年由 D.L.Shell提出来的。该方法的基本思想是:先将整个待排元素序列分割 成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插 入排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元 素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下 (接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两 种方法有较大提高。
想是:把n个待排序的元素看成为一个有序表和一个无序 表,开始时有序表中只包含一个元素,无序表中包含有n1个元素,排序过程中每次从无序表中取出第一个元素, 把它的排序码依次与有序表元素的排序码进行比较,将它 插入到有序表中的适当位置,使之成为新的有序表。
例:待排记录 49 38 65 97 76 13 27 49
3 约定 在本章中 1)为简洁起见,对待排记录只写出其排序码序列
如对待排记录((09,10),(06,10.5),(033,9.8),(051,10)) 只写出其关键字序列(10,10.5,9.8,10) 2)将按关键字递增的顺序排序
3)待排序记录用顺序表存储
顺序表类型说明
#define MAXSIZE 20 //一个用作示例的小顺序表的最大长度
} }//InsertSort
0 12345678 9
49 38 65 76 97 13 27 49
初始时,有序子表中 只有一个元素
看一下外层For循环 i=5 时算法的执行的情况 0 1 2 3 4 5 6 7 8 9
38 49 65 97 76 13 27 49
L.r[5]为待插入元素
0 1 23 4 5 67 8 9
24
例 初始: 49 38 65 97 76 13 27 48 55 4
取d1=5 一趟分组:
49
38
65
97
76
13
27
48
55
4
一趟排序: 13 27 48 55 4 49 38 65 97 76
取d2=3 二趟分组:
13
27
48
55
4
49 38 65 97 76
二趟排序: 13 4 48 38 27 49 55 65 97 76 取d3=1
从时间分析:
基本正序 ,只比较,不移动元素,待插入元素传送2次。总比较次 数为(n-1),传送次数为2(n-1)。O(T)=O(n)
基本逆序,对每个元素i, 比较i次,总次数 i=2i=(n+2)(n+1)/2, 移动 i-1+2次 , i=2(i+1)=(n+4)(n-1)/2。 O(T)=O(n2) 综合两种情况,平均n2 /4
2.存贮方式 待排序的记录序列通常有下列三种存贮方法: 1)顺序表 2)静态链表:在排序过程,只需修改指针,不需要移动记录; 3)待排记录本身存放在连续单元中,同时另建一索引表——用于 存放各记录存贮位置;排序时不移动记录本身,而移动索引表中 的记录“地址”,在排序结束后再按地址调整记录的存贮位置
5).稳定与不稳定
因为排序码可以不是记录的关键字,同一排序码值可能对应 多个记录。对于具有同一排序码的多个记录来说,若采用的排序 方法使排序后记录的相对次序不变,则称此排序方法是稳定的, 否则称为不稳定的。
6).内排序与外排序
按照排序过程中使用内外存的不同将排序方法分为内排序和 外排序。若排序过程全部在内存中进行,则称为内排序;若排序 过程需要不断地进行内存和外存之间的数据交换,则称为外排序。 内排序大致可分为五类:插入排序、交换排序、选择排序、归并 排序和分配排序。本章仅讨论内排序。
特点: 1) 算法简单 2) 时间复杂度为O(n2 ) 3)初始序列基本(正向)有序时,时间复杂度为O(n) 4)稳定排序
该方法适用于记录基本(正向)有序或n较少的情况
10.2.2 其他插入排序
1.二分插入排序 1)基本思想 二分插入排序(Binary Insert Sort)的基本思想是:在有序表中采用