码迷,mamicode.com
首页 > 编程语言 > 详细

不同角度看排序

时间:2017-10-13 00:43:52      阅读:42      评论:0      收藏:0      [点我收藏+]

标签:反序   不同的   避免   多个   交换   堆排序   堆排   两种   结合   

1 按照排序特性分类

首先按照排序本身的操作特性可以分为下面几种:

(1)插入排序

a.直接插入排序(Insert Sort)          O(n^2)(稳定)

b.折半插入排序(Binary Insert Sort)        (不稳定)

c.希尔排序(Shell Sort)                           (不稳定)


(2)交换排序

a.冒泡排序(Bubble Sort)         O(n^2)                  (稳定)

b.快速排序(Quick Sort)??      O(nlogn)           (不稳定)


(3)选择排序

a.直接选择排序(Select Sort)           O(n^2)           (不稳定)

b.锦标赛排序(Tournament Sort)     O(nlogn)  (不稳定)

c. 堆排序(Heap Sort)                    O(nlogn)   (不稳定)
d. 归并排序(Merge Sort)              O(nlogn)                   稳定,还取决与,每段的排序算法选择。      比如每段长度大于2 用稳定的直接插入排序,然后再归并,不一定要到长度为2 的粒度再归并。

 e.基数排序(Radix Sort)                O(d(n+radix))          (稳定性 待定)

2 .每种排序算法的特点:

(1  冒泡排序:在最优情况下只需要经过n- 1次比较即可得出结果,(这个最优情况那就是序列己是正序,从100K的正序结果可以看出结果正是如此),

但在最坏情况下,即倒序(或一个较小值在最 后),下沉算法将需要n(n-1)/2次比较。

所以一般情况下,特别是在逆序时,它很不理想。它是对数据有序性非常敏感的排序算法。

 

冒泡排序2:它是冒泡排序的改良(一次下沉再一次上浮),最优情况和最坏情况与冒泡排序差不多,但是一般情况下它要好过冒泡排序,它一次下沉,再一次上浮,这样避免了因一个数的逆序,而造成巨大的比较。如(2,3,4,…,n- 1,n,1),用冒泡排序需要n(n-1)/2次比较,而此排序只要3轮,共比较(n-1)+(n-2)+(n-3)次,第一轮1将上移一位,第二轮1将 移到首位,第三轮将发现无数据交换,序列有序而结束。

但它同样是一个对数据有序性非常敏感的排序算法,只适合于  数据基本有序的排序。

 

(2  快速排序:它同样是冒泡排序的改进,它通过一次交换能消除多个逆序,这样可以减少逆序时所消耗的扫描和数据交换次数。

在最优情况下,它的排序时间复杂度为O(nlog2n)。 即每次划分序列时,能均匀分成两个子串。

但最差情况下它的时间复杂度将是O(n^2)。

即每次划分子串时,一串为空,另一串为m-1(程序中的100K正 序和逆序就正是这样,如果程序中采用每次取序列中部数据作为划分点,那将在正序和逆时达到最优)。

从100K中正序的结果上看“快速排序”会比“冒泡排 序”更慢,这主要是“冒泡排序”中采用了提前结束排序的方法。有的书上这解释“快速排序”,在理论上讲,如果每次能均匀划分序列,它将是最快的排序算法, 因此称它作快速排序。虽然很难均匀划分序列,但就平均性能而言,它仍是基于关键字比较的内部排序算法中速度最快者。

 

(3  直接选择排序:简单的选择排序,它的比较次数一定:n(n- 1)/2。也因此无论在序列何种情况下,它都不会有优秀的表现(从上100K的正序和反序数据可以发现它耗时相差不多,相差的只是数据移动时间),可见对 数据的有序性不敏感。它虽然比较次数多,但它的数据交换量却很少。所以我们将发现它在一般情况下将快于冒泡排序。

 

(4  堆排序:由于它在直接选择排序的基础上利用了比较结果形成。效率提高很大。它完成排序的总比较次数为O(nlog2n)。它是对数据的有序性不敏感的一种算法。

但堆排序将需要做两个步骤:-是建堆,二是排序(调整堆)。所以一般在小规模的序列中不合适,但对于较大的序列,将表现出优越的性能。

 

(5 直接插入排序:简 单的插入排序,每次比较后最多移掉一个逆序,因此与冒泡排序的效率相同。

但它在速度上还是要高点,这是因为在冒泡排序下是进行值交换,而在插入排序下是值 移动,所以直接插入排序将要优于冒泡排序。

直接插入法也是一种对数据的有序性非常敏感的一种算法。在有序情况下只需要经过n-1次比较,在最坏情况下,将需要n(n-1)/2次比较。

 

(6 希尔排序:增量的选择将影响希尔排序的效率。

但是无论怎样选择增量,最后一定要使增量为1,进行一次直接插入排序。但它相对于直接插入排序,由于在子表中每进行一次比较,就可能移去整个经性表中的多个逆序,从而改善了整个排序性能。希尔排序算是一种基于插入排序的算法,所以对数据有序敏感。

 

(7归并排序:归并排序是一种非就地排序,将需要与待排序序列一样多的辅助空间。在使用它对两个己有序的序列归并,将有无比的优势。

其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlog2n)。对数据的有序性不敏感。若数据节点数据量大,那将不适合。但可改造成索引操作,效果将非常出色。

 

 (8基数排序:在程序中采用的是以数值的十进制位分解,然后对空间采用一次性分配,因此它需要较多的辅助空间(10*n+10),

(但我们可以进行其它分解,如以一个字节分解,空间采用链表将只需辅助空间n+256)。

基数排序的时间是线性的(即O(n))。由此可见,基数排序非常吸引人,但它也不是就地排序,若节点数据量大时宜改为索引排序。

但基数排序有个前提,要关键字能象整型、字符串这样能分解,若是浮点型那就不行了。

总结 各种排序方法比较      简单排序中直接插入最好,快速排序最快,当文件为正序时,直接插入和冒泡均最佳。

3. 按平均时间将排序分为四类

(1)平方阶(O(n2))排序      一般称为简单排序,例如直接插入、直接选择和冒泡排序;

(2)线性对数阶(O(nlgn))排序      如快速、堆和归并排序;

(3)O(n1+£)阶排序      £是介于0和1之间的常数,即0<£<1,如希尔排序;

(4)线性阶(O(n))排序      如桶、箱和基数排序。

4. 影响排序效果的因素

     因为不同的排序方法适应不同的应用环境和要求,所以选择合适的排序方法应综合考虑下列因素:   

①待排序的记录数目n;   

②记录的大小(规模);   

③关键字的结构及其初始状态;   

④对稳定性的要求;   

⑤语言工具的条件;   

⑥存储结构;   

⑦时间和辅助空间复杂度等。

5 .不同条件下,排序方法的选择

(1)若n较小(如n≤50),可采用直接插入或直接选择排序。      

当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插人,应选直接选择排序为宜。

(2)若文件初始状态基本有序(指正序),则应选用直接插人、冒泡或随机的快速排序为宜;

(3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或归并排序。    

 

 快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;      

堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。       

若要求排序稳定,则可选用归并排序。

但本章介绍的从单个记录起进行两两归并的   排序算法并不值得提倡,通常可以将它和直接插入排序结合在一起使用。

先利用直接插入排序求得较长的有序子文件,然后再两两归并之。

 

因为直接插入排序是稳定 的,所以改进后的归并排序仍是稳定的。

6.排序算法的稳定性

 1) 稳定的:如果存在多个具有相同排序码的记录,经过排序后,这些记录的相对次序仍然保持不变,则这种排序算法称为稳定的。    

插入排序、冒泡排序、归并排序、分配排序(桶式、基数)都是稳定的排序算法。   

 

  2)不稳定的:否则称为不稳定的。   

  直接选择排序、堆排序、shell排序、快速排序都是不稳定的排序算法

不同角度看排序

标签:反序   不同的   避免   多个   交换   堆排序   堆排   两种   结合   

(0)
(0)
   
举报
评论 一句话评论(0
0条  
登录后才能评论!
© 2014 mamicode.com 版权所有 京ICP备13008772号-2
迷上了代码!