Namespaces
Variants

std::stable_sort

来自 zh.cppreference.net
 
 
算法库
受约束算法及范围算法 (C++20)
受约束算法,例如 ranges::copy、ranges::sort……
排序及相关操作
划分操作
(C++11)    

排序操作
二分查找操作
(在划分范围上)
集合操作(在已排序范围上)
合并操作(在已排序范围上)
堆操作
最小/最大操作
(C++11)
(C++17)
字典序比较操作
排列操作


 
定义于头文件 <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,
                  RandomIt first, RandomIt last );
(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,
                  RandomIt first, RandomIt last, Compare comp );
(4) (C++17 起)

以非降序排序范围 [first, last) 中的元素。保证等价元素的顺序保持不变。

1) 元素按 (C++20 前)(C++20 起)operator<进行std::less{}排序。
3) 元素按 comp 进行排序。
2,4) 与 (1,3) 相同,但按 policy 执行。
仅当以下表达式的值为 true 时,这些重载才参与重载决议:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(C++20 前)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(C++20 起)

如果满足以下任一条件,则行为未定义:

(C++11 前)
(C++11 起)

参数

first, last - 定义待排序元素 范围 的迭代器对
policy - 使用的 执行策略
comp - 比较函数对象(即满足 Compare 要求的对象),当第一个参数 小于 (即排序在 之前 )第二个参数时返回​ true 。

比较函数的签名应等价于如下形式:

bool cmp ( const Type1 & a, const Type2 & b ) ;

虽然签名不需要包含 const & ,但函数不得修改传递给它的对象,且必须能够接受所有(可能为 const 的) Type1 和 Type2 类型的值,无论其 值类别 为何(因此不允许 Type1& ,也不允许 Type1 ,除非对于 Type1 移动操作等价于拷贝操作 (C++11 起) )。
类型 Type1 和 Type2 必须使得 RandomIt 类型的对象在解引用后能隐式转换到这两个类型。 ​

类型要求
-
RandomIt 必须满足 LegacyRandomAccessIterator 的要求。
-
Compare 必须满足 Compare 的要求。

复杂度

给定 N 为 last - first :

1,2) O(N·log(N)) 次比较(使用 operator < (C++20 前) std:: less { } (C++20 起) ),前提是有足够的额外内存可用;否则需要 O(N·log 2
(N))
次比较。
3,4) O(N·log(N)) 次比较器 comp 的调用(在有足够额外内存的情况下),否则为 O(N·log 2
(N))
次调用。

异常

带有名为 ExecutionPolicy 模板参数的重载按以下方式报告错误:

  • 如果作为算法一部分调用的函数执行抛出异常,且 ExecutionPolicy 是某个 标准策略 ,则调用 std::terminate 。对于其他任何 ExecutionPolicy ,其行为由实现定义。
  • 如果算法无法分配内存,则抛出 std::bad_alloc 。

可能的实现

另请参阅 libstdc++ 与 libc++ 中的实现。

注释

此函数尝试分配一个与待排序序列大小相等的临时缓冲区。若分配失败,则选择效率较低的算法。

功能测试 宏 值 标准 功能特性
__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; // 不参与比较
};
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 个元素进行排序
(函数模板 & 算法函数对象)
将元素分为两组,同时保留每组内元素的相对顺序
(函数模板 & 算法函数对象)
对一定范围内的元素进行排序,同时保留等价元素之间的相对顺序
(算法函数对象)