1. 程式人生 > >資料結構與演算法之美專欄學習筆記-排序優化

資料結構與演算法之美專欄學習筆記-排序優化

選擇合適的排序演算法

回顧

 

選擇排序演算法的原則

1)線性排序時間複雜度很低但使用場景特殊,如果要寫一個通用排序函式,不能選擇線性排序。

2)為了兼顧任意規模資料的排序,一般會首選時間複雜度為O(nlogn)的排序演算法來實現排序函式。

3)同為O(nlogn)的快排和歸併排序相比,歸併排序不是原地排序演算法,所以最優的選擇是快排。


優化快速排序

導致快排時間複雜度降為O(n^2)的原因是分割槽點選擇不合理,

最理想的分割槽點是:被分割槽點分開的兩個分割槽中,資料的數量差不多。

優化分割槽點有2種常用方法:

三數取中法

從區間的首、中、尾分別取一個數,然後比較大小,取中間值作為分割槽點。

如果要排序的陣列比較大,那三數取中可能就不夠用了,可能要五數取中或者十數取中。

隨機法

每次從要排序的區間中,隨機選擇一個元素作為分割槽點。

遞迴發生堆疊溢位的解決方法

限制遞迴深度,一旦遞迴超過了設定的閾值就停止遞迴。

在堆上模擬實現一個函式呼叫棧,手動模擬遞迴壓棧、出棧過程,這樣就沒有系統棧大小的限制。

 

通用排序函式實現技巧

1.資料量不大時,可以採取用時間換空間的思路
2.資料量大時,優化快排分割槽點的選擇
3.防止堆疊溢位,可以選擇在堆上手動模擬呼叫棧解決
4.在排序區間中,當元素個數小於某個常數是,可以考慮使用O(n^2)級別的插入排序
5.用哨兵簡化程式碼,每次排序都減少一次判斷,儘可能把效能優化到極致

 

思考

C#中的排序函式都是用什麼排序演算法實現的?有哪些優化的技巧?