各類排序方法的性能比較:算法
排序法shell |
平均時間數組 |
最壞狀況性能 |
最好狀況spa |
穩定度.net |
額外空間blog |
備註排序 |
1.直接插入內存 |
O(n2)ci |
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),可是佔用很大的空間,桶內可用快排等 |
(一)基於比較的排序算法:
一、第一類——插入排序法:直接插入排序,希爾。以及不常見的Tree sort、Library sort、Patience sorting 。
二、第二類——交換排序法:冒泡、快排(由冒泡改進而來)。以及不常見的雞尾酒排序、奇偶排序、梳排序、Gnome sort 。
三、第三類——選擇排序法:直接選擇、堆排序。
四、第四類——歸併排序法:歸併排序。以及不常見的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。
來源:http://blog.csdn.net/cangchen/article/details/44962973