std::ranges::sort
来自 cppreference.com
定义在头文件 <algorithm> 中 |
||
调用签名 |
||
template< std::random_access_iterator I, std::sentinel_for<I> S, class Comp = ranges::less, class Proj = std::identity > |
(1) | (自 C++20 起) |
template< ranges::random_access_range R, class Comp = ranges::less, class Proj = std::identity > |
(2) | (自 C++20 起) |
按非递减顺序对范围 [
first,
last)
中的元素进行排序。等效元素的顺序不保证被保留。
如果对于指向序列的任何迭代器 it
和任何非负整数 n
(使得 it + n
是指向序列元素的有效迭代器),std::invoke(comp, std::invoke(proj, *(it + n)), std::invoke(proj, *it)) 的计算结果为 false,则序列是根据比较器 comp 排序的。
1) 元素使用给定的二元比较函数 comp 进行比较。
本页描述的类函数实体是niebloids,即
实际上,它们可以作为函数对象实现,或使用特殊的编译器扩展。
内容 |
[编辑] 参数
first, last | - | 定义要排序的范围的迭代器-哨兵 |
r | - | 要排序的范围 |
comp | - | 要应用于投影元素的比较 |
proj | - | 要应用于元素的投影 |
[编辑] 返回值
等于 last 的迭代器。
[编辑] 复杂度
𝓞(N·log(N)) 比较和投影,其中 N = ranges::distance(first, last).
[编辑] 可能的实现
请注意,典型实现使用 Introsort。另请参见 MSVC STL 和 libstdc++ 中的实现。
struct sort_fn { template<std::random_access_iterator I, std::sentinel_for<I> S, class Comp = ranges::less, class Proj = std::identity> requires std::sortable<I, Comp, Proj> constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {}) const { if (first == last) return first; I last_iter = ranges::next(first, last); ranges::make_heap(first, last_iter, std::ref(comp), std::ref(proj)); ranges::sort_heap(first, last_iter, std::ref(comp), std::ref(proj)); return last_iter; } template<ranges::random_access_range R, class Comp = ranges::less, class Proj = std::identity> requires std::sortable<ranges::iterator_t<R>, Comp, Proj> constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {}) const { return (*this)(ranges::begin(r), ranges::end(r), std::move(comp), std::move(proj)); } }; inline constexpr sort_fn sort {}; |
[编辑] 备注
std::sort 使用 std::iter_swap 交换元素,而 ranges::sort
则使用 ranges::iter_swap(它为 iter_swap
执行 ADL,不像 std::iter_swap)
[编辑] 示例
运行此代码
#include <algorithm> #include <array> #include <functional> #include <iomanip> #include <iostream> void print(auto comment, auto const& seq, char term = ' ') { for (std::cout << comment << '\n'; auto const& elem : seq) std::cout << elem << term; std::cout << '\n'; } struct Particle { std::string name; double mass; // MeV template<class Os> friend Os& operator<<(Os& os, Particle const& p) { return os << std::left << std::setw(8) << p.name << " : " << p.mass << ' '; } }; int main() { std::array s {5, 7, 4, 2, 8, 6, 1, 9, 0, 3}; namespace ranges = std::ranges; ranges::sort(s); print("Sort using the default operator<", s); ranges::sort(s, ranges::greater()); print("Sort using a standard library compare function object", s); struct { bool operator()(int a, int b) const { return a < b; } } customLess; ranges::sort(s.begin(), s.end(), customLess); print("Sort using a custom function object", s); ranges::sort(s, [](int a, int b) { return a > b; }); print("Sort using a lambda expression", s); Particle particles[] { {"Electron", 0.511}, {"Muon", 105.66}, {"Tau", 1776.86}, {"Positron", 0.511}, {"Proton", 938.27}, {"Neutron", 939.57} }; ranges::sort(particles, {}, &Particle::name); print("\nSort by name using a projection", particles, '\n'); ranges::sort(particles, {}, &Particle::mass); print("Sort by mass using a projection", particles, '\n'); }
输出
Sort using the default operator< 0 1 2 3 4 5 6 7 8 9 Sort using a standard library compare function object 9 8 7 6 5 4 3 2 1 0 Sort using a custom function object 0 1 2 3 4 5 6 7 8 9 Sort using a lambda expression 9 8 7 6 5 4 3 2 1 0 Sort by name using a projection Electron : 0.511 Muon : 105.66 Neutron : 939.57 Positron : 0.511 Proton : 938.27 Tau : 1776.86 Sort by mass using a projection Electron : 0.511 Positron : 0.511 Muon : 105.66 Proton : 938.27 Neutron : 939.57 Tau : 1776.86
[编辑] 参见
(C++20) |
对范围的前 N 个元素进行排序 (niebloid) |
(C++20) |
对元素范围进行排序,同时保留相等元素之间的顺序 (niebloid) |
(C++20) |
将元素范围划分为两组 (niebloid) |
将范围排序为升序 (函数模板) |