排序算法小结

    最近刚好有空,所以打算全面的看一遍排序,故先总结一下之前和最近看的一些排序算法

一、排序的基本概念

1.排序  

     首先来看一下排序的基本概念,排序(Sorting)是按关键字的非递减或非递增顺序对一组记录重新进行排列的操作。

2.排序的稳定性

     这是一个重要的性质,当排序排序记录中的关键字Ki(i=1,2,...,n)都不相同时,则任何一个记录的无序序列经排序后得到的结果唯一;反之,当待排序的序列中存在两个或两个以上关键字相等的记录时,则排序所得的结果不唯一。假设Ki=Kj(1<=i<=n,1<=j<=n,i!=j),且在排序前的序列中Ri领先于Rj(即i<j)。若在排序后的序列中Ri仍领先于Rj,则称所用的排序方法是稳点的;反之,若可能使排序后的序列中Rj领先于Ri,则称所用的排序方法是不稳定的。注意,排序算法的稳定性是针对所有记录而言的。也就是说,在所有的待排序记录中,只要有一组关键字的实例不满足稳定性要求,则该排序方法就是不稳定的。虽然稳定的排序方法和不稳定的排序方法排序结果不同,但不能说不稳定的排序方法就不好,各有各的适用场合。

3.内部排序和外部排序

    由于待排序记录的数量不同,使得排序过程中数据所占用的存储设备会有所不同。根据在排序过程中记录所占用的存储设备,可以将排序方法分为两大类:一类是内部排序,指的是待排序记录全部存放在计算机内存中进行排序的过程;另一类是外部排序,指的是待排序记录的数量很大,以致内存依次不能容纳全部记录,在排序过程中尚需对外存进行访问的排序过程。

二、排序方法的分类

    内部排序的方法很多,但就其全面性能而言,很难提出一种被认为是最好的方法,每一种方法都有各自的优缺点,适合在不同的环境(如记录的初始排列状态等)使用。内部排序的分类方法也很多,可以分为以下两种情况

1.根据排序过程中依据的原则来分类

1)插入排序:直接插入排序(将当前值直接插入到以排序好的序列中),折半插入排序(采用二分法查找插入位置),希尔排序(利用缩小增量减少记录个数和使关键字基本有序)。

2)交换排序:冒泡排序(交换相邻的位置,每次使最大的归位),快速排序(跳跃式比较、交换两个数)。

3)选择排序:简单选择排序(每次找出最小,让其归位),堆排序(利用二叉树,减少比较次数)。

4)归并排序(将两个或两个以上有序表合并成一个有序表的过程)。

5)基数排序(不比较关键字大小,通过对待排序记录进行若干趟“分配”和“收集”)

2.根据排序过程中所需的工作量来分类

1)简单的排序方法,其时间复杂度为O(n^2);

2)先进的排序方法,其时间复杂度为O(nlog2n);

3)基数排序,其时间复杂度为O(d*n);

三、待排序记录的存储方式

1.顺序表,记录之间的次序关系由存储位置决定,实现排序需要移动记录。

2.链表,记录之间的次序关系由指针指示,实现排序不需要移动记录,仅需修改指针即可这种排序方式称为链表排序。

四、排序算法效率和评价指标

    就排序方法的全面性能而言,很难提出一种被认为是最好的方法。目前,评价排序算法好坏的指标主要有两点。

1.执行时间

    对于排序操作,时间主要消耗在关键字之间的比较和记录的移动上(这里,只考虑以顺序表方式存储待排序记录),排序算法的时间复杂度由着两个指标决定。因此可以认为,高效率的排序算法的比较次数和移动次数都应该尽可能地少。

2.辅助空间

   空间复杂度由排序算法所需的辅助空间决定。辅助空间是除了存放待排序记录占用的空间之外,执行算法所需要的其他存储空间。理想的空间复杂度为O(1),即算法执行期间所需要的辅助空间与待排序的数据量无关。

五、小结

下面从时间复杂度、空间复杂度和稳点性几个方面对这些方法做比较。


      从表的时间复杂度的平均情况来看,直接插入排序、冒泡排序和简单选择排序的速度较慢,而其他排序方法的速度较快。从算法实现的角度来看,速度较慢的算法实现过程比较简单,称之为简单的排序方法;而速度较快的算法可以看做是对某一排序算法的改进(Shell是由直接插入改进、堆排序是由直接选择改进、快速排序是由冒泡排序改进),称之为先进的排序方法,但这些算法实现比较复杂。总体来看,各种排序算法各有优缺点,没有哪一种是绝对最优的。在使用时需根据不用情况适当选用,甚至可将多种方法结合起来使用。一般综合考虑以下因素:

1)待排序的记录个数;

2)记录本身的大小;

3)关键字的结构及初始状态;

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

5)存储结构。

   根据这些因素和上表所做的比较,可以得出以下几点结论。

1)当待排序的记录个数n较小时,n^2和nlog2n的差别不大,可以选用简单的排序方法。

而当关键字基本有序时,可选用直接插入排序或冒泡排序,排序速度很快,其中直接插入排序最为简单常用、性能最佳。

2)当n较大时,应该选用先进的排序方法。对于先进的排序方法,从平均时间性能而言,快速排序最佳,是目前基于比较的排序方法中最好的方法。但在最坏情况下,即当关键字基本有序时,快速排序的递归深度为n,时间复杂度为O(n^2),空间复杂度为O(n)。堆排序和归并排序不会出现快速排序的最坏情况,但归并排序的辅助空间较大。这样,当n较大时,具体的选用原则是:

①当关键字分布随机,稳点性不做要求时,可采用快速排序;

②当关键字基本有序,稳点性不做要求时,可采用堆排序;

③当关键字基本有序,内存允许且要求排序稳点时,可采用归并排序。

3)可以将简单的排序方法和先进的排序方法结合。例如,当n较大时,可以先将待排序序列划分成若干子序列,分别进行直接插入排序,然后再利用归并排序,将有序子序列合并成一个完整的有序序列。或者,在快速排序中,当划分区间的长度小于某值时,可以转而调用直接插入排序。

4)基数排序的时间复杂度也可以写成O(d*n)。因此,它适用于n值很大而关键字较小的序列。若关键字很大,而序列中的大多数记录的“最高位关键字”均不同,则亦可先按“最高位关键字”不同将序列分成若干个“小”的子序列,而后进行直接插入排序。但基数排列使用条件有严格的要求:需要知道各级关键字的主次关系和各级关键字的取值范围,即只适用于像整数和字符这类有明显结构特征的关键字,当关键字的取值范围为无穷集合时,则无法使用基数排序。

5)由于大多数情况下是按记录的主关键字进行的,则所用的排序方法是否稳定无关紧要。若排序按记录的次关键字进行,则必须采用稳定的排序方法。一般来说,如果排序的过程中的”比较”是在“相邻的两个记录关键字”间进行的,则排序方法是稳定的。值得提出的是,稳定性是由方法本身提出的,证明一种排序方法是否稳定的,要从算法本身的步骤中加以证明;而证明排序方法是不稳定的,只需要列出一个不稳定的实例来说明。

6)平时在讨论排序方法中,多数采用顺序表实现的。若记录本身信息量较大,为避免移动记录耗费大量时间,可以采用链式结构。比如直接插入排序、归并排序都易于在链表上实现。但像折半插入排序、希尔排序、快速排序和堆排序,却难于在链表上实现。

附:

各种排序算法性能对比分析点击打开链接


各种排序的实现

1.直接插入排序

2.折半插入排序

3.希尔排序

4.冒泡排序

5.快速排序

6.简单选择排序

7.堆排序

8.归并排序

9.基数排序



  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值