std::stable_sort
來自 cppreference.com
定義於標頭檔案 <algorithm> |
||
template< class RandomIt > void stable_sort( RandomIt first, RandomIt last ); |
(1) | (C++26 起為 constexpr) |
template< class ExecutionPolicy, class RandomIt > void stable_sort( ExecutionPolicy&& policy, |
(2) | (C++17 起) |
template< class RandomIt, class Compare > void stable_sort( RandomIt first, RandomIt last, Compare comp ); |
(3) | (C++26 起為 constexpr) |
template< class ExecutionPolicy, class RandomIt, class Compare > void stable_sort( ExecutionPolicy&& policy, |
(4) | (C++17 起) |
以非降序對範圍 [
first,
last)
中的元素進行排序。保證保持等價元素的順序。
3) 元素根據 comp 排序。
2,4) 同 (1,3),但按 policy 執行。
僅當滿足所有以下條件時,這些過載才參與過載決議
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> 為 true。 |
(C++20 前) |
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> 為 true。 |
(C++20 起) |
如果滿足以下任何條件,則行為是未定義的:
|
(C++11 前) |
|
(C++11 起) |
目錄 |
[編輯] 引數
first, last | - | 定義待排序元素 範圍 的迭代器對 |
policy | - | 要使用的 執行策略 |
comp | - | 比較函式物件(即滿足 Compare 要求的物件),若第一個引數小於(即在第二個引數之前排序)第二個引數則返回 true。 比較函式的簽名應等效於以下內容 bool cmp(const Type1& a, const Type2& b); 儘管函式簽名不需要含有 const&,但函式不可修改傳遞給它的物件,且必須能接受 |
型別要求 | ||
-RandomIt 必須滿足 LegacyRandomAccessIterator 的要求。 | ||
-Compare 必須滿足 Compare 的要求。 |
[編輯] 複雜度
給定 N 為 last - first
1,2) 如果有足夠的額外記憶體可用,使用 operator<(C++20 前)std::less{}(C++20 起) 進行 O(N·log(N)) 次比較,否則進行 O(N·log2
(N)) 次比較。
(N)) 次比較。
3,4) 如果有足夠的額外記憶體可用,對比較器 comp 進行 O(N·log(N)) 次應用,否則進行 O(N·log2
(N)) 次應用。
(N)) 次應用。
[編輯] 異常
帶有模板引數 ExecutionPolicy
的過載按如下方式報告錯誤
- 若作為演算法一部分呼叫的函式執行丟擲異常,且
ExecutionPolicy
為標準策略之一,則呼叫 std::terminate。對於任何其他ExecutionPolicy
,行為是實現定義的。 - 如果演算法未能分配記憶體,則丟擲 std::bad_alloc。
[編輯] 可能的實現
[編輯] 注意
此函式嘗試分配一個大小等於要排序序列的臨時緩衝區。如果分配失敗,則選擇效率較低的演算法。
特性測試宏 | 值 | 標準 | 特性 |
---|---|---|---|
__cpp_lib_constexpr_algorithms |
202306L |
(C++26) | constexpr 穩定排序,過載 (1)、(3) |
[編輯] 示例
執行此程式碼
#include <algorithm> #include <array> #include <iostream> #include <string> #include <vector> struct Employee { int age; std::string name; // Does not participate in comparisons }; bool operator<(const Employee& lhs, const Employee& rhs) { return lhs.age < rhs.age; } #if __cpp_lib_constexpr_algorithms >= 202306L consteval auto get_sorted() { auto v = std::array{3, 1, 4, 1, 5, 9}; std::stable_sort(v.begin(), v.end()); return v; } static_assert(std::ranges::is_sorted(get_sorted())); #endif int main() { std::vector<Employee> v{{108, "Zaphod"}, {32, "Arthur"}, {108, "Ford"}}; std::stable_sort(v.begin(), v.end()); for (const Employee& e : v) std::cout << e.age << ", " << e.name << '\n'; }
輸出
32, Arthur 108, Zaphod 108, Ford
[編輯] 另請參閱
將一個範圍按升序排序 (函式模板) | |
對一個範圍的前 N 個元素進行排序 (函式模板) | |
將元素分成兩組,同時保留它們的相對順序 (函式模板) | |
(C++20) |
對一個範圍的元素進行排序,同時保留相等元素之間的順序 (演算法函式物件) |