各种排序方法的比较

各种排序方法的比较

排序方法有很多,它们各有优缺点,没有绝对最好的和最坏的排序方法,只有最符合某个使用场景的方法。在选用排序方法的时候,我们应该综合考虑以下方面:

1)时间复杂度;

2) 空间复杂度;

3)稳定性;

4)算法简单性;

5)待排序记录个数n的大小;

6)记录本身信息量的大小;

7)关键码的分布情况;

下面先从每个方面逐个对常用的一些算法进行比较和分析,然后给出综合讨论。

一、时间复杂度和空间复杂度

排序方法平均情况最好情况最坏情况辅助空间
冒泡排序(交换排序)O(n^{2})O(n)O(n^{2})O(1)
快速排序(冒泡排序的一种改进)O(n^{_{}}{log_{2}}^{n})O(n^{_{}}{log_{2}}^{n})O(n^{2})O({log_{2}}^{n})~O(n^{^{}})
     
直接插入排序(插入排序)O(n^{2}O(n)O(n^{2})O(1)
希尔排序(直接插入排序的一种改进)O(n^{_{}}{log_{2}}^{n})~O(n^{2})O(n^{1.3})O(n^{2}O(1)
     
简单选择排序(选择排序)O(n^{2})O(n^{2})O(n^{2})O(1)
堆排序(简单选择排序的一种改进)O(n^{_{}}{log_{2}}^{n})O(n^{_{}}{log_{2}}^{n})O(n^{_{}}{log_{2}}^{n})O(1)
     

归并排序

O(n^{_{}}{log_{2}}^{n})O(n^{_{}}{log_{2}}^{n})O(n^{_{}}{log_{2}}^{n})O(n)
     
桶式排序(分配排序之一)    
基数排序(分配排序之一)O(d(n+m))O(d(n+m))O(d(n+m))O(m)

二、稳定性

给定一个原始记录序列(r_{1},r^{2},...,r_{n}),其相应的关键码分别是(k_{1},k_{2},...,k_{n})。如果,在原序列中,k_{i} = k_{j},且r_{i}r_{j}之前,在排序后的序列中,r_{i}仍在r_{j}之前,则这种排序算法稳定;否则称为不稳定。

稳定的排序方法直接插入排序、冒泡排序、归并排序和基数排序
不稳定的排序方法希尔排序、快速排序、简单选择排序和堆排序

 

三、算法简单性

 

简单方法冒泡排序、直接插入排序算法、简单选择排序、桶式排序
改进方法快速排序、希尔排序、堆排序、归并排序、基数排序

四、待排序的记录个数n的大小

         n越小,采用简单排序方法越合适;n越大,采用改进的排序方法越合适。(  因为n越小,O(n^{2})和O(n^{_{}}{log_{2}}^{n})的差距就越小,并且输入和调试简单算法比输入和调试改进算法要少用许多时间。)

五、一个记录包含的信息量的大小

          一个记录包含的信息量越大,占用的存储空间就越多,移动记录所花费的时间就越多,所以对记录的移动次数较多的算法不利。

             三种简单排序方法中记录的移动次数的比较

排序方法最好情况最坏情况平均情况
直接插入排序O(n)O(n^{2})O(n^{2})
冒泡排序0O(n^{2})O(n^{2})
简单选择排序 0O(n)O(n)

        从上表可以看出,当记录包含的信息量较大时,选择简单选择排序会获得比其他两种排序方法更好的排序效率。这里还有一种方法可以减少移动记录的时间,尤其是当记录包含的信息较多时,可以使用数组的每一个元素存储指向记录的指针,在这种情况下,移动只需要对指针进行操作(增加了空间,但节省了时间)。

六、关键码的分布情况

       当待排序记录序列符合期望的序列时,这对直接插入排序和冒泡排序来说是最好的情况,但对快速排序来说是最坏的情况。简单选择排序、堆排序、归并排序和基数排序的时间性能与关键码的分布情况无关。

 

综合考虑以上六个方面,可以有以下大致结论:

(1)当待排序记录个数n较大,关键码分布较随机,且对稳定性不作要求时,宜采用快速排序。

 (2)当待排序记录个数n较大,内存空间允许,且要求排序稳定时,采用归并排序为宜。

 (3)当待排序记录个数n较大,关键码分布可能出现正序(已经排好顺序)或者逆序(与期待的顺序相反)的情况,且对稳定性不做要求时,采用堆排序或归并排序。

   (4) 当待排序记录个数n较大,而只要找出最小的前几个记录,采用堆排序或简单选择排序。例如,在堆排序中,如果想找到序列中第k大的记录,则需要O(n+k{log_{2}}^{n})时间;如果k很小,这会快很多。

 

 

参考书籍:

数据结构(C++版)王红梅 胡明 王涛 编著

 

 

 

 

              

   

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值