std::nth_element
Defined in header <algorithm> |
||
|---|---|---|
template< class RandomIt > void nth_element( RandomIt first, RandomIt nth, RandomIt last ); |
(1) | (constexpr с C++20) |
template< class ExecutionPolicy, class RandomIt >
void nth_element( ExecutionPolicy&& policy,
RandomIt first, RandomIt nth, RandomIt last );
|
(2) | (с C++17) |
template< class RandomIt, class Compare >
void nth_element( RandomIt first, RandomIt nth, RandomIt last,
Compare comp );
|
(3) | (constexpr с C++20) |
template< class ExecutionPolicy, class RandomIt, class Compare >
void nth_element( ExecutionPolicy&& policy,
RandomIt first, RandomIt nth, RandomIt last,
Compare comp );
|
(4) | (с C++17) |
nth_element — это алгоритм частичной сортировки, который переупорядочивает элементы в [first, last) таким образом:
- Элемент, на который указывает
nth, изменяется на тот элемент, который бы находился на этом месте, если бы[first,last)были отсортированы. - Все элементы перед этим новым элементом
nthменьше или равны элементам после нового элементаnth.
Более формально, nth_element частично сортирует диапазон [first, last) в порядке возрастания таким образом, что для любого i в диапазоне[first, nth) и для любого j в диапазоне [nth, last) выполняется следующее условие:
!(*j < *i),comp(*j, *i) == false.Элемент, помещенный в позицию nth, точно соответствует элементу, который бы находился на этом месте, если бы весь диапазон был полностью отсортирован.
nth может быть конечным итератором, в этом случае функция не оказывает никакого влияния.
operator<.comp.policy. Эти перегрузки не участвуют в разрешении перегрузки, если |
|
(до C++20) |
|
|
(с C++20) |
Параметры
| first, last | - | итераторы случайного доступа, определяющие диапазон сортировки |
| nth | - | итератор случайного доступа, определяющий точку разбиения сортировки |
| policy | - | политика выполнения. Подробности см. в политике выполнения. |
| comp | - | объект функции сравнения (т.е. объект, удовлетворяющий требованиям Compare), который возвращает true если первый аргумент меньше (т.е. упорядочен раньше) второго. Подпись функции сравнения должна быть эквивалентна следующей:
Хотя подпись не должна содержать const&, функция не должна изменять передаваемые ей объекты и должна уметь принимать все значения типа (возможно, const) |
| Требования к типу | ||
-RandomIt должен удовлетворять требованиям ValueSwappable и LegacyRandomAccessIterator. |
||
-Тип разыменованного RandomIt должен удовлетворять требованиям MoveAssignable и MoveConstructible. |
||
Возвращаемое значение
(ничего)
Сложность
std::distance(first, last) в среднем.N = last - first.Исключение
Перегрузки с параметром шаблона, имеющим имя ExecutionPolicy сообщают об ошибках следующим образом:
- Если выполнение функции, вызываемой в рамках алгоритма, вызывает исключение, и
ExecutionPolicyявляется одной из стандартных политик, вызываетсяstd::terminate. Для любой другойExecutionPolicy, поведение определяется реализацией. - Если алгоритм не может выделить память, выбрасывается
std::bad_alloc.
Примечания
Используемый алгоритм обычно Introselect, хотя и другие алгоритмы выбора с подходящей сложностью в среднем случае допускаются.
Возможная реализация
См. также реализации в libstdc++, libc++ и msvc stl.
Пример
#include <algorithm>
#include <cassert>
#include <functional>
#include <iostream>
#include <numeric>
#include <vector>
void printVec(const std::vector<int>& vec)
{
std::cout << "v = {";
for (char sep[]{0, ' ', 0}; const int i : vec)
std::cout << sep << i, sep[0] = ',';
std::cout << "};\n";
}
int main()
{
std::vector<int> v {5, 10, 6, 4, 3, 2, 6, 7, 9, 3};
printVec(v);
auto m = v.begin() + v.size() / 2;
std::nth_element(v.begin(), m, v.end());
std::cout << "\nThe median is " << v[v.size() / 2] << '\n';
// The consequence of the inequality of elements before/after the Nth one:
assert(std::accumulate(v.begin(), m, 0) < std::accumulate(m, v.end(), 0));
printVec(v);
// Note: comp function changed
std::nth_element(v.begin(), v.begin() + 1, v.end(), std::greater{});
std::cout << "\nThe second largest element is " << v[1] << '\n';
std::cout << "The largest element is " << v[0] << '\n';
printVec(v);
}Возможный вывод:
v = {5, 10, 6, 4, 3, 2, 6, 7, 9, 3};
The median is 6
v = {3, 2, 3, 4, 5, 6, 10, 7, 9, 6};
The second largest element is 9
The largest element is 10
v = {10, 9, 6, 7, 6, 3, 5, 4, 3, 2};См. также
| возвращает наибольший элемент в диапазоне (шаблон функции) |
|
| возвращает наименьший элемент в диапазоне (шаблон функции) |
|
| копирует и частично сортирует диапазон элементов (шаблон функции) |
|
| сортирует диапазон элементов, сохраняя порядок между равными элементами (шаблон функции) |
|
| сортирует диапазон в порядке возрастания (шаблон функции) |
|
|
(C++20) |
частично сортирует заданный диапазон, гарантируя, что он разбит по заданному элементу (niebloid) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/algorithm/nth_element