常用排序算法性能比較,及常見面試題

轉載於:https://blog.csdn.net/cangchen/article/details/44962973

各種排序方法的性能比較:

排序法

平均時間

最壞情況

最好情況

穩定度

額外空間

備註

1.直接插入

O(n2)

O(n2)

O(n)

穩定

O(1)

大部分已排序時較好(簡單)

1.希爾

O(nlogn)

O(nlogn)

與步長相關

不穩定

O(1)

n小時較好(較複雜)

2冒泡

O(n2)

O(n2)

O(n)

穩定

O(1)

n小時較好(簡單)

2快排

O(nlogn)

O(n2)

O(nlogn)

不穩定

O(logn)

n大時較好,基本有序時反而不好(較複雜)

3.直接選擇

O(n2)

O(n2)

O(n2)

不穩定

O(1)

n小時較好(簡單)

3堆排序

O(nlogn)

O(nlogn)

O(nlogn)

不穩定

O(1)

n大時較好(較複雜)

4歸併

O(nlogn)

O(nlogn)

O(nlogn)

穩定

O(n)

n大時較好(較複雜)

基數

O(d(n+r))

O(d(n+r))

O(d(n+r))

穩定

O(r)

d爲位數,r爲基數(較複雜)

計數

O(n+k)

O(n+k)

O(n+k)

穩定

O(n+k)

優於比較排序法,0~k爲數值範圍

桶排序

O(n+c)

O (nlogn):所有的元素落到一個桶中

O(n)

穩定

O(n+m)

n爲數的個數,m爲桶數

c = n*(logn-logm)

桶越多,效率越高,n=m,達到O(n),但是佔用很大的空間,桶內可用快排等


(一)基於比較的排序算法:

1、第一類——插入排序法:直接插入排序,希爾。以及不常見的Tree sort、Library sort、Patience sorting 。

2、第二類——交換排序法:冒泡、快排(由冒泡改進而來)。以及不常見的雞尾酒排序、奇偶排序、梳排序、Gnome sort 。

3、第三類——選擇排序法:直接選擇、堆排序。

4、第四類——歸併排序法:歸併排序。以及不常見的Strand sort。

(二)非基於比較的排序算法:

上表中藍色粗體標識:基數、計數、桶排序。


性能分析及選擇排序方法的考量:

O(n^2)的分析:

在數據規模較小時(9W之內),直接插入(略微好於簡單選擇)、簡單選擇差不多。當數據較大時,冒泡排序算法的時間代價是最昂貴的。 另外,普通排序算法基本上都是相鄰元素進行比較,因此O(N^2)的排序基本都是穩定的。

O(nlogn)的分析:

其中快速排序無疑是最優秀的。其次是歸併排序和希爾排序,堆排序稍微差一些。

先進算法分析:

(1) 就時間性能而言,希爾排序、快速排序堆排序和歸併排序都是較爲先進的排序方法。耗時遠小於O(N^2)級別的算法。

(2) 先進算法之中,快排的效率是最高的。但其缺點十分明顯:在待排序列基本有序的情況下,會蛻化成起泡排序,時間複雜度       接近 O(N^2)

(3) 希爾排序的性能讓人有點意外,這種增量插入排序的高效性完全說明了:在基本有序序列中,直接插入排序絕對能達到令人      吃驚的效率。但是希爾排序對增量的選擇標準依然沒有較爲滿意的答案,要知道增量的選取直接影響排序的效率。

(4) 歸併排序的效率非常不錯,在數據規模較大的情況下,它比希爾排序和堆排序都要好。

(5)堆排序在數據規模較小的情況下還是表現不錯的,但是隨着規模的增大,時間代價也開始和shell和歸併兩種排序拉開距離。

(6) 多數先進排序都因爲跳躍式的比較,降低了比較次數,但是也犧牲了排序的穩定性。

總的來說,並不存在最佳的排序算法。必須針對待排序列自身的特點來選擇良好的算法。


不同條件下,排序方法的選擇

1.插入、冒泡排序的速度較慢,但參加排序的序列局部或整體有序時,這種排序能達到較快的速度。

反而在這種情況下,快速排序反而慢了。

2.當n較小時,對穩定性不作要求時宜用選擇排序,對穩定性有要求時宜用插入或冒泡排序。

3.若待排序的記錄的關鍵字在一個明顯有限範圍內時,且空間允許是用桶排序。

4.當n較大時,關鍵字元素比較隨機,對穩定性沒要求宜用快速排序。

5.當n較大時,關鍵字元素可能出現本身是有序的,對穩定性有要求時,空間允許的情況下,宜用歸併排序。

6.當n較大時,關鍵字元素可能出現本身是有序的,對穩定性沒有要求時宜用堆排序。


下面有一些指導性的意見:

(1) 數據規模很小,而且待排序列基本有序的情況下,選擇直接插入排序或冒泡排序對是上策。不要小看它O(N^2)級別。

(2) 數據規模不是很大,完全可以使用內存空間。而且待排序列雜亂無序(越亂越開心)快速排序永遠是不錯的選擇,當然付出log(N)的額外空間(爲棧所需的輔助空間)是值得的。

(3) 海量級別的數據,必須按塊存放在外存(磁盤)中。此時的歸併排序是一個比較優秀的算法,在數據規模較大的情況下,它比希爾排序和堆排序都要好。


常考問題:

1.簡單選擇排序、堆排序和歸併排序的時間性能不隨記錄序列中關鍵字的分佈而改變。 

2.直接插入排序在某一趟結束後未必能選出一個元素放在其最終位置;但是堆排序、冒泡(在首趟即可確定最大值和最小值)、快排可以。

3.已知數組中的每個元素距離最終位置不遠,採用直接插入排序最節省時間。

4.直接選擇排序關鍵字比較次數和記錄的初始排列順序無關,都爲n(n-1)/2。

5.對n個元素執行快排,在進行第一次劃分時,關鍵字的比較次數總是n-1。

 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章