名稱空間
變體
操作

std::sort

來自 cppreference.com
< cpp‎ | 演算法
 
 
演算法庫
有約束演算法與針對範圍的演算法 (C++20)
有約束的演算法,例如 ranges::copyranges::sort 等……
執行策略 (C++17)
排序及相關操作
劃分操作
排序操作
二分搜尋操作
(於已劃分範圍上)
集合操作(於已排序範圍上)
歸併操作(於已排序範圍上)
堆操作
最小/最大值操作
(C++11)
(C++17)
字典序比較操作
排列操作
C 庫
數值操作
未初始化記憶體上的操作
 
定義於標頭檔案 <algorithm>
template< class RandomIt >
void sort( RandomIt first, RandomIt last );
(1) (C++20 起為 constexpr)
template< class ExecutionPolicy, class RandomIt >

void sort( ExecutionPolicy&& policy,

           RandomIt first, RandomIt last );
(2) (C++17 起)
template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );
(3) (C++20 起為 constexpr)
template< class ExecutionPolicy, class RandomIt, class Compare >

void sort( ExecutionPolicy&& policy,

           RandomIt first, RandomIt last, Compare comp );
(4) (C++17 起)

將範圍 [firstlast) 中的元素按非降序排序。不保證相等元素的順序。

1) 元素根據 operator<(直至 C++20)std::less{}(自 C++20 起) 排序。
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&,但函式不可修改傳遞給它的物件,且必須能夠接受 Type1Type2 型別(可能帶 const)的所有值,無論其 值類別 (因此不允許 Type1&,除非 Type1 的移動等價於複製,也不允許 Type1(自 C++11 起))。
型別 Type1Type2 必須使得型別為 RandomIt 的物件可以被解引用,然後隱式轉換為兩者之一。​

型別要求
-
RandomIt 必須滿足 LegacyRandomAccessIterator 的要求。
-
Compare 必須滿足 Compare 的要求。

[編輯] 複雜度

給定 Nlast - first

1,2) 使用 operator<(直至 C++20)std::less{}(自 C++20 起) 進行 O(N·log(N)) 次比較。
3,4) O(N·log(N)) 次應用比較器 comp

[編輯] 異常

帶有模板引數 ExecutionPolicy 的過載按如下方式報告錯誤

  • 若作為演算法一部分呼叫的函式丟擲異常且 ExecutionPolicy標準策略 之一,則呼叫 std::terminate。對於任何其他 ExecutionPolicy,行為是實現定義的。
  • 如果演算法未能分配記憶體,則丟擲 std::bad_alloc

[編輯] 可能的實現

亦見 libstdc++libc++ 中的實現。

[編輯] 注意

LWG713 之前,複雜度要求允許 sort() 僅使用 快速排序 (Quicksort) 實現,這在最壞情況下可能需要 O(N2
)
次比較。

內省排序 (Introsort) 可以處理所有情況,具有 O(N·log(N)) 次比較(在平均情況下不產生額外開銷),因此通常用於實現 sort()

libc++ 直到 LLVM 14 才實現修正後的時間複雜度要求。

[編輯] 示例

#include <algorithm>
#include <array>
#include <functional>
#include <iostream>
#include <string_view>
 
int main()
{
    std::array<int, 10> s{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
 
    auto print = [&s](std::string_view const rem)
    {
        for (auto a : s)
            std::cout << a << ' ';
        std::cout << ": " << rem << '\n';
    };
 
    std::sort(s.begin(), s.end());
    print("sorted with the default operator<");
 
    std::sort(s.begin(), s.end(), std::greater<int>());
    print("sorted with the standard library compare function object");
 
    struct
    {
        bool operator()(int a, int b) const { return a < b; }
    }
    customLess;
 
    std::sort(s.begin(), s.end(), customLess);
    print("sorted with a custom function object");
 
    std::sort(s.begin(), s.end(), [](int a, int b)
                                  {
                                      return a > b;
                                  });
    print("sorted with a lambda expression");
}

輸出

0 1 2 3 4 5 6 7 8 9 : sorted with the default operator<
9 8 7 6 5 4 3 2 1 0 : sorted with the standard library compare function object
0 1 2 3 4 5 6 7 8 9 : sorted with a custom function object
9 8 7 6 5 4 3 2 1 0 : sorted with a lambda expression

[編輯] 缺陷報告

下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
LWG 713 C++98 O(N·log(N)) 時間複雜度僅在平均情況下要求 在最壞情況下要求

[編輯] 另請參閱

對一個範圍的前 N 個元素進行排序
(函式模板) [編輯]
對一個範圍的元素進行排序,同時保留相等元素之間的順序
(函式模板) [編輯]
將一個範圍按升序排序
(演算法函式物件)[編輯]