排序是把一组无序的数据元素按照关键字值递增(或递减)的顺序重新排列成有序列的过程。

  根据在排序过程中待排序的所有数据元素是否全部被放置在内存中,可将排序方法分为内部排序外部排序两大类。

    (1)内部排序: 整个排序过程完全在内存中进行,排序时不涉及数据的内、外存交换。

    (2)外部排序: 由于待排序记录数据量太大,内存无法容纳全部数据,排序需要借助外部存储设备才能完成。

  排序算法的评价主要有两点: 一是在数据量规模一定的条件下,算法执行所消耗的平均时间,排序操作的时间主要消耗在关键字之间的比较和数据元素的移动上,因此我们可以认为高效率的排序算法应该尽可能少的比较次数和尽可能少的移动次数;二是执行算法所需要的辅助存储空间。辅助存储空间是指在数据规模量一定的条件下,除了待排序元素占用的存储空间之外,执行算法所需要的其他存储空间。理想的空间效率是算法执行期间所需要的辅助空间域待排序的数据量无关。

  排序算法的稳定性:如果待排序的记录序列有多个数据元素的关键字值相同,排序后这些数据元素的相对次序保持不变,则称这种排序算法是稳定的,否则称之为不稳定的。

  待排序记录序列的存储结构。待排序记录序列是线性结构,可以用顺序存储结构链式存储结构表示。对于顺序存储结构进行排序时,是对序列中的记录本身进行物理重排(通过关键字之间的比较判断,将记录移动到合适的位置)。而对以链表作为存储结构的序列进行排序时,无序移动记录,仅需修改指针。

  下面将分别讨论对常见的几种内部排序算法:直接插入排序希尔排序选择排序堆排序冒泡排序快速排序归并排序以及基数排序

 

  在这里我们来总结一下排序算法优缺点,上述的排序算法使用的场合各不相同,在选择排序方法时应该考虑的因素有:

    (1) 待排序记录的数据 n  的大小

    (2) 记录本身除关键字外的其他信息量的大小

    (3)关键字的情况

    (4)对排序稳定性的要求

    (5)语言工具的条件,辅助空间的大小等。

  综合考虑上面的因素,可以得出的结论:

    (1) 若排序记录的数目 n 较小 (如 n <= 50), 可以采用直接插入排序或简单选择排序。由于直接插入排序所需的记录移动操作比简单选择排序多,因而当记录本身信息量较大时,用简单选择排序比较好。

    (2) 若记录的初始状态已经按关键字分布基本有序,可以采用直接插入排序或冒泡排序。

    (3) 若记录的数目 n 较大, 则可以采用时间复杂度为 O(n log n) 的排序方法(如快速排序、堆排序或归并排序等)。快速排序的平均性能最好,在待排序列已经按关键字随机分布时,快速排序最合适。快速排序在最坏情况下的时间复杂度是O(n2),而堆排序在最坏的情况下的时间复杂度不会发生变化,并且所需的辅助空间少于快速排序。但这两种排序都是不稳定的排序,若需要稳定的排序方法,可以使用归并排序。

    (4) 基数排序可在 O(d*n)(d 为关键字的个数, n 为序列的长度(待排序元素个数))时间内完成 n 个记录的排序,但基数排序只适合与字符串和整数这种有明显结构特征的关键字。当 n 很大、 d 很小时, 可采用基数排序。

    (5) 待排序的记录非常多时,为避免大量的时间进行记录的移动,可以采用链式存储结构。直接插入排序和和归并排序可以非常容易地在链表上实现,但是快速排序和堆排序却很难在链表上实现。此时,可以提取关键字建立索引表或者引入一个数组作为辅助,然后对索引表或数组进行排序。

    在上面的内部排序方法中,所需要计算的时间来看,快速排序、归并排序、堆排序是非常有优势的。但是归并排序需要大小为 n 的辅助空间,快速排序需要一个栈。除了快速排序之外、堆排序、希尔排序不稳定外,其他的排序都是稳定的。

 

                                各种排序算法性能比较

   排序方法      最好情况时间复杂度   最坏情况时间复杂度  平均时间复杂度   辅助空间  稳定性   备注

    插入排序        O(n)          O(n2)        O(n2)               O(1)           稳定      序列基本稳定时,插入排序时最佳的排序算法

    希尔排序        O(n log n)       O(n log n)         O(n log n)          O(1)           不稳定   复杂度计算很复杂,因不同的实现而又所不同

    冒泡排序        O(n2)            O(n2)         O(n2)                  O(1)         稳定

       选择排序        O(n2)               O(n2)         O(n2)                 O(1)         稳定       无论初始序列如何,记录的比较次数不受影响   

     堆排序                 O(n log n)         O(n log n)         O(n log n)          O(1)          不稳定

   归并排序        O(n log n)          O(n log n)         O(n log n)          O(n)           稳定       无论初始序列如何,记录的比较次数不受影响

   基数排序        O(d(n+rd))                   O(d(n+rd))       O(d(n+rd))        O(rd)           稳定         待排序为 n 个记录,d 个关键字,关键字取值范围 rd

  快速排序           O(n log n)                    O(n2)                O(n log n)         O(log n)       不稳定  需要log n 的栈空间

 

 

       注:主要参考彭军、向毅主编的 《数据结构与算法》

 

 

 

 

posted on 2013-10-20 21:32  surgewong  阅读(637)  评论(0编辑  收藏  举报