排序是计算机程序设计中的一种重要的操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列。
由于待排序的记录数量不同,使得排序过程中涉及的存储器不同,可将排序方法分为两大类:一类是内部排序,指的是待排序记录存放在随机存储器中进行的排序过程;另一类是外部排序,指的是待排序记录数量比较大,以至内存一次不能容纳全部记录,在排序过程中尚需对外存进行访问的排序过程。下面主要讨论内部排序。
通常,排序过程中需要进行两种操作:一是比较两个关键字的大小;二是要将记录从一个位置移动至另一个位置。
1、插入排序算法
1.1、直接插入排序:
直接插入排序是一种最简单的排序方法,它的基本操作是将一个记录插入到一个已排好序的有序表中,从而得到一个新的、记录数增1的有序表。
下面是它的程序实现:
直接插入排序算法简单,且容易实现,它的时间复杂度是O(n2)。当待排序记录的数量n很小时,这是一种很好的算法,但是当待排序序列中的记录数量n比较大时,则不宜采用直接插入排序。因此需要在直接插入排序的基础上,从减少“比较”和“移动”这两个操作的次数上,寻找改进的插入排序方法,比较有代表性的有折半插入排序和希尔排序算法。
1.2、折半插入排序:
由于插入排序的基本操作是在一个有序表中进行查找和插入,因而,这个“查找”工作可用“折半查找”(二分查找)来实现,由此进行的插入排序称之为折半插入排序。
折半插入排序所需要的附加存储空间和直接插入排序相同,从时间上比较,折半插入排序仅减少了关键字间比较的次数,而记录的移动次数不变,因此,折半插入排序的时间复杂度仍为O(n2)。
1.3、希尔排序:
希尔排序是一种改进的插入排序类算法,又称为“缩小增量排序”。直接插入排序算法的时间复杂度是O(n2),但是,若待排序记录序列为“正序”时,即不需要移动记录,其时间复杂度可提高至O(n)。因此可以设想,如果待排序记录序列按关键字“基本有序”,那么直接插入排序的效率就可以大大提高;从另一方面,由于直接插入排序算法简单,在n值很小时效率也比较高。希尔排序正是从这两点分析出发对直接插入排序进行改进得到的一种插入排序算法。
希尔排序的基本思想是:先将整个待排序记录序列分隔成若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,在对全体记录进行一次直接插入排序。
从上述排序过程可以看出,希尔排序有一个特点:子序列的构成不是简单的“逐段分隔”,而是将相隔某个“增量”的记录组成一个子序列。