對冒泡、快排、堆排這3個算法做了驗證,結果分析如下:
一、結果分析
時間消耗:快排 < 堆排 < 冒泡。
空間消耗:冒泡O(1) = 堆排O(1) < 快排O(logn)~O(n) 。
應用推薦:
1、速度最快、且允許占用少量的空間:選快排。
2、速度快且空間最小(O(1)):選堆排。
3、要求相同大小的元素順序不能變更:選冒泡。
4、完全不考慮空間消耗的:用基排(極限情況下時間O(n),限制較多,不單獨說了)。
冒泡排序:
優點:穩定、空間復雜度O(1)
缺點:慢
時間復雜度最好為n(傳入的數組有序,一輪循環即可截止),最壞為n^2,平均為n^2。呈現為n增大10倍,耗時增加100倍。
在對穩定性有要求的場景下,即相同大小的元素先后順序不能變更,冒泡排序表現較佳。快排和堆排都是不穩定的。冒泡每次比較相鄰的元素,只有不等時才考慮是否交換,所以冒泡不會改變相同大小的元素的順序,是穩定的排序算法。
快速排序:
優點:快
缺點:不穩定、空間復雜度O(logn)~O(n)
時間復雜度最好為nlogn,最壞為n^2(每次key都在首或尾,棧深度達到n),平均為nlogn。
為了減小最壞情況發生的概率,我們在選擇Key的時候,取了首、尾和中間這3個元素里的中間大小的元素作為Key。
相比其他兩種算法,快排需要依靠函數棧(遞歸)或其他類型的存儲空間(非遞歸)來存儲每次划分的區間。最好的情況下,每次都平均划分,需要額外的logn的空間;最壞情況下每次都划分在首或尾,則額外的空間花銷達到n。
堆排序:
優點:快(比較快排慢點)、空間復雜度O(1)
缺點:不穩定
時間復雜度穩定在nlogn。
快排和堆排的時間復雜度都是nlogn,為什么快排會更快呢?因為堆排的復雜度的常系數更大。我們從另一個角度來看。堆排每次將堆頂元素取出,取而代之的是堆底元素。而這個新的堆頂元素顯然是比較小的,肯定要比其中一個子節點小。於是調整堆時,拿剛換上來的較小的根與下面的子節點比較,結果有很大可能是要交換多次(甚至於被換回堆底)。這種比較是概率不均等的、很不划算的。而堆排中充斥着大量這種不均等的比較,造成很多多余的交換,這就是為什么堆排會更慢。
二、源碼
冒泡:https://www.cnblogs.com/JoZSM/p/9768735.html
快排:https://www.cnblogs.com/JoZSM/p/9768781.html
堆排:https://www.cnblogs.com/JoZSM/p/9783872.html
驗證代碼:涉及到造數據、存文件等,代碼較長,不貼出來了。有需要的可以留言。