std::ranges::partial_sort
Определён в заголовочном файле <algorithm> | ||
|---|---|---|
| Сигнатура вызова | ||
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
partial_sort( I first, I middle, S last, Comp comp = {}, Proj proj = {} );
| (1) | (начиная с C++20) |
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>
partial_sort( R&& r, ranges::iterator_t<R> middle, Comp comp = {},
Proj proj = {} );
| (2) | (начиная с C++20) |
1) Переставляет элементы так, чтобы диапазон
[first, middle) содержал наименьшие отсортированные middle - first элементов диапазона [first, last).
Порядок равных элементов не гарантируется. Порядок оставшихся элементов в диапазоне
[middle, last) является неопределённым.
Элементы сравниваются с помощью заданной бинарной функции сравнения
comp и проецируются с помощью функционального объекта proj.
2) То же, что (1), но в качестве диапазона используется
r, как если бы ranges::begin(r) использовался в качестве first, а ranges::end(r) — в качестве last.Описанные на этой странице функциональные сущности — это функциональные объекты алгоритмов (неофициально известные как niebloids), то есть:
- При вызове любой из них нельзя указывать явные списки аргументов шаблона.
- Ни одна из них не видна для поиска, зависящего от аргументов.
- Если любая из них найдена посредством обычного неквалифицированного поиска в качестве имени слева от оператора вызова функции, поиск, зависящий от аргументов, подавляется.
Параметры
| first, last | - | пара итератора и сентинела, задающая диапазон переставляемых элементов |
| r | - | диапазон переставляемых элементов |
| middle | - | диапазон [first, middle) будет отсортирован |
| comp | - | компаратор, применяемый к спроецированным элементам |
| proj | - | проекция, применяемая к элементам |
Возвращаемое значение
Итератор, равный last.
Сложность
\(\scriptsize \mathcal{O}(N\cdot\log{(M)})\)𝓞(N·log(M)) сравнений и вдвое больше проекций, где \(\scriptsize N\)N — ranges::distance(first, last), а \(\scriptsize M\)M — ranges::distance(first, middle).
Возможная реализация
struct partial_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, I middle, S last, Comp comp = {}, Proj proj = {}) const
{
if (first == middle)
return ranges::next(first, last);
ranges::make_heap(first, middle, comp, proj);
auto it {middle};
for (; it != last; ++it)
{
if (std::invoke(comp, std::invoke(proj, *it), std::invoke(proj, *first)))
{
ranges::pop_heap(first, middle, comp, proj);
ranges::iter_swap(middle - 1, it);
ranges::push_heap(first, middle, comp, proj);
}
}
ranges::sort_heap(first, middle, comp, proj);
return it;
}
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, ranges::iterator_t<R> middle, Comp comp = {}, Proj proj = {}) const
{
return (*this)(ranges::begin(r), std::move(middle), ranges::end(r),
std::move(comp), std::move(proj));
}
};
inline constexpr partial_sort_fn partial_sort {};
|
Пример
#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
#include <vector>
void print(const auto& v)
{
for (const char e : v)
std::cout << e << ' ';
std::cout << '\n';
}
void underscore(int n)
{
while (n-- > 0)
std::cout << "^ ";
std::cout << '\n';
}
int main()
{
static_assert('A' < 'a');
std::vector<char> v {'x', 'P', 'y', 'C', 'z', 'w', 'P', 'o'};
print(v);
const int m {3};
std::ranges::partial_sort(v, v.begin() + m);
print(v), underscore(m);
static_assert('1' < 'a');
std::string s {"3a1b41c5"};
print(s);
std::ranges::partial_sort(s.begin(), s.begin() + m, s.end(), std::greater {});
print(s), underscore(m);
}
Вывод:
x P y C z w P o C P P y z x w o ^ ^ ^ 3 a 1 b 4 1 c 5 c b a 1 3 1 4 5 ^ ^ ^
См. также
|
(C++20) | копирует диапазон элементов и частично сортирует его (функциональный объект алгоритма) |
|
(C++20) | сортирует диапазон элементов (функциональный объект алгоритма) |
|
(C++20) | сортирует диапазон элементов, сохраняя относительный порядок эквивалентных элементов (функциональный объект алгоритма) |
|
(C++20) | находит N-й элемент так, как если бы диапазон был отсортирован (функциональный объект алгоритма) |
|
(C++20) | создаёт max-кучу из диапазона элементов (функциональный объект алгоритма) |
|
(C++20) | удаляет наибольший элемент из max-кучи (функциональный объект алгоритма) |
|
(C++20) | добавляет элемент в max-кучу (функциональный объект алгоритма) |
|
(C++20) | преобразует max-кучу в отсортированный диапазон элементов (функциональный объект алгоритма) |
| сортирует первые N элементов диапазона (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/ranges/partial_sort