第7章 排序
本章内容
本章主要介绍多种内部排序算法,包括它们的排序过程、排序时间复杂度以及实现等等,本章在考研中是重点内容。本章几个内部排序的代码实现都比较重要。
7.1 排序的分类
内部排序是指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列。[2]
外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。[3]
在这一章,我们主要讨论的是内部排序下面的多种排序算法。
7.2 稳定性
待排序的序列中有两个或两个以上相同的项。排序前和排序后,这些相同项的相对位置发生变化,则属于不稳定,否则是稳定的。
7.3 插入类排序
插入类排序包括:简单(直接)插入排序、折半插入排序和希尔排序。
7.3.1 简单(直接)插入排序
思路:将待排序记录插入已排好的记录中,不断扩大有序序列。即:将待排序记录插入有序序列,重复n-1次。
【例子1】:将52,49,80,36,14,58,61进行直接插入排序。
分析:
平均(n^2)/4,时间复杂度O(n^2),空间复杂度O(1),稳定的。
代码:
void InsertSort(int R[], int n) {
int i, j;
int temp;
for (i = 2; i <= n; ++i) {
temp = R[i];
j = i-1;
while(j >= 1 && temp < R[j]) {
R[j+1] = R[j];
--j;
}
R[j+1] = temp;
}
}
7.3.2 折半插入排序
思路:在直接插入排序中,查找插入位置时采用折半查找的方法。其基本条件是序列已经有序。
【例子2】:现在的序列是13,38,49,65,76,97,需要在此基础上折半插入27和49。
(1) low=1,high=6,m=(1+6)/2=3->49,27<49,因此27位于49的低半区间;
(2) low=1,high=m-1=3-1=2,m=(1+2)/2=1->13,27>13,因此27位于13的高半区间;
(3) low=m+1=2,high=2,m=2->38,27<38,因此27位于38低半区间;
(4) low=2,high=m-1=1,low>high,结束
(5) 27在13与38之间
分析:时间复杂度最好是O(n),最坏是O(n^2),平均情况O(n^2),空间复杂度O(1),比直接插入