排序是程式設計中最高頻算法之一。STL(標準模板庫)提供了高效、泛型、經過嚴格測試的排序組件,讓開發者脫離底層算法實現細節,專注業務邏輯。本文系統梳理 STL 所有排序算法的特性、適用場景與選擇策略。
所有排序算法接受迭代器範圍 [first, last),要求**隨機存取迭代器**(除 partition/stable_partition 外)。支援自定義比較函數(仿函數)。
| 算法 | 功能 | 穩定性 | 典型複雜度 | 適用容器 |
|---|---|---|---|---|
sort | 全量排序 | 不穩定 | O(N log N) 平均 | vector, deque, string, array |
stable_sort | 穩定全量排序 | 穩定 | O(N log N) ~ O(N log²N) | vector, deque, string, array |
partial_sort | 部分排序(前 N 小) | 不穩定 | O(N log M) | vector, deque, string, array |
partial_sort_copy | 複製並部分排序 | 不穩定 | O(N log M) | 任意輸入迭代器 + 隨機輸出 |
nth_element | 定位第 N 元素 | 不穩定 | O(N) 平均 | vector, deque, string, array |
partition | 條件分區 | 不穩定 | O(N) | Forward Iterator 以上 |
stable_partition | 穩定條件分區 | 穩定 | O(N log N) ~ O(N) | Forward Iterator 以上 |
is_sorted | 檢查是否有序 | - | O(N) | Forward Iterator 以上 |
預設使用 std::less<T>(即 operator<)。常用仿函數:
less<T>、greater<T>、less_equal<T>、greater_equal<T>equal_to<T>、not_equal_to<T>自定義類型可:
operator<「穩定」指**相等元素(按比較函數判定相等)相對順序不變**。例如按字串長度排序時,"apple" 與 "winter" 長度相同,stable_sort 保證原順序,sort 可能打亂。
sort vs stable_sortsort:IntroSort(快排+堆排+插排混合),平均 O(N log N),最壞 O(N log N),**不穩定**,速度最快。stable_sort:歸併排序,穩定,需額外記憶體,記憶體充足時 O(N log N),否則 O(N log²N)。partial_sort / partial_sort_copypartial_sort_copy 適合輸入為單向迭代器或需保留原容器場景。nth_elementpartition)。partition / stable_partitionlist::sort()(指針操作、迭代器不失效)、list::merge()、list::remove_if() 等。需 partial_sort/nth_element 時,先複製到 vector。按執行速度由快到慢(同等條件下):
partition / stable_partition — O(N)nth_element — 平均 O(N)partial_sort — O(N log M)sort — O(N log N)stable_sort — O(N log N) ~ O(N log²N)Effective STL 選擇原則:
- 全量排序 →
sort(不需穩定)或stable_sort(需穩定)- Top N →
partial_sort- 第 N 元素 / Top N 不需內部有序 →
nth_element- 條件分區 →
partition/stable_partition- list 容器 → 成員函數或複製到 vector
選對算法不僅關乎效能,更體現代碼意圖清晰度。理解每個算法的複雜度、穩定性、迭代器要求與適用場景,是 C++ 開發者進階的必修課。