排序的稳定性:当存在两个关键字相同的元素Ri,Rj,再排序前Ri领先于Rj(即i<j),当排完序Ri依旧领先于Rj,则称此排序方法为稳定的,否则则称为不稳定的。
内排序和外排序:
- 内排序:指待排元素记录全部存放在计算机内部进行的排序过程;
- 外部排序:待排记录的数量很大,一直内存一次不能全部容纳全部记录,在排序过程中尚需对外部存储进行访问的排序过程。
各种排序对比:
排序方法 | 时间复杂度 | 空间复杂度 | 稳定性 | ||
最好情况 | 最坏情况 | 平均情况 | |||
直接插入排序 | O(n) | O(n^2) | O(n^2) | O(1) | 稳定 |
折半插入排序 | O(n*log2^n) | O(n^2) | O(n^2) | O(1) | 稳定 |
希尔排序 | O(n^1.3) | O(1) | 不稳定 | ||
冒泡排序 | O(n) | O(n^2) | O(n^2) | O(1) | 稳定 |
简单选择排序 | O(n^2) | O(n^2) | O(n^2) | O(1) | 稳定 |
快速排序 | O(n*log2^n) | O(n^2) | O(n*log2^n) | O(log2^n) | 不稳定 |
堆排序 | O(n*log2^n) | O(n*log2^n) | O(n*log2^n) | O(1) | 不稳定 |
归并排序 | O(n*log2^n) | O(n*log2^n) | O(n*log2^n) | O(n) | 稳定 |
基数排序 | O(d(n+rd)) | O(d(n+rd)) | O(d(n+rd)) | O(n+rd) | 稳定 |
在使用时需根据不同情一般综合考虑以下因素:
(1 )待排序的记录个数;
(2)记录本身的大小;
(3)关键字的结构及初始状态;
(4)对排序稳定性的要求;
(5)存储结构。
根据这些因素和表所做的比较,可以得出以下几点结论:
(1)当待排序的记录个数n较小时,n和nlog2^n的差别不大,可选用简单的排序方法。当当关键字基本有序时,可选用直接插人排序或冒泡排序,排序速度很快,其中直接插人排序最为局单常用、性能最佳。
(2)当n较大时,应该选用先进的排序方法。对于先进的排序方法,从平均时间性能而言,快速排序最佳,是目前基于比较的排序方法中最好的方法。但在最坏情况下,即当关键字基本有序时,快速排序的递归深度为n,时间复杂度为0(n^2),空间复杂度为O(n)。堆排序和归并排序不会出现伏速排序的最坏情况,但归并排序的辅助空间较大。这样,当n较大时,具体选用的原则是:
①当关键字分布随机,稳定性不做要求时,可采用快速排序;
②当关键字基本有序,稳定性不做要求时,可采用堆排序,
③当关键字基本有序,内存允许且要求排序稳定时,可采用归并排序。
(3)可以将简单的排序方法和先进的排序方法结合使用。例如,当n较大时,可以先将待排序序列划分成若千子序列,分别进行直接插人排序,然后再利用归并排序,将有序子序列合并成一个完整的有序序列。或者,在快速排序中,当划分子区间的长度小于某值时,可以转而调用直接插人排序算法。
(4)基数排序的时间复杂度也可写成O(d*n)。因此,它最适用于n值很大而关键字较小的序列。若关键字也很大,而序列中大多数记录的“最高位关键字”均不同,则亦可先按“最高位关键字”不同将序列分成若干“小”的子序列,而后进行直接插人排序。但基数排序使用条件有严格的要求:需要知道各级关键字的主次关系和各级关键字的取值范围,即只适用于像整数和字符这类有明显结构特征的关键字, 当关键字的取值范围为无穷集合时,则无法使用基数排序。
(5)从方法的稳定性来比较,基数排序是稳定的内排方法,所有时间复杂度为O(n^2)的简单排序法也是稳定的,然而,快速排序、堆排序和希尔排序等时间性能较好的排序方法都是不稳定的。
一般来说, 如果排序过程中的“比较”是在“相邻的两个记录关键字”间进行的,则排序方法是稳定的。值得提出的是,稳定性是由方法本身决定的,对不稳定的排序方法而言,不管其描述形式如何,总能举出一个说明不稳定的实例来。反之,对稳定的排序方法,可能有的描述形式会引起不稳定,但总能找到一一种 不引起不稳定的描述形式。由于大多数情况下排序是按记录的主关键字进行的,则所用的排序方法是否稳定无关紧要。若排序按记录的次关键字进行,则必须采用稳定的排序方法。
(6)讨论的排序方法中,多数是采用顺序表实现的。若记录本身信息量较大,为避免移动记录耗费大量时间,可采用链式存储结构。比如直接插人排序归并排序都易于在链表上实但像折半插人排序、希尔排序、快速排序和堆排序,却难于在链表上实现。
体对于外部排序,常用的方法是归并方法,这种方法主要由两个独立的阶段组成:
第一,把待持序的文件划分成若干个子文件;
第二,逐趟归并子文件,最后形成对整个文件的排序。为减少日并中外存读写的次数,提高外排序的效率,般通过增大归并路数和减少初始归并段个数两种方案对归并算法进行改进,其中,“多路平衡归并”的方法可以增加归并段的个数,“置换选择”的方法可以减少初始归并段的个数。