std::nth_element

Header: <algorithm>

nth_element rearranges elements in [first,last) such that after the rearrangement:

# Declarations

template< class RandomIt >
void nth_element( RandomIt first, RandomIt nth, RandomIt last );

(constexpr since C++20)

template< class ExecutionPolicy, class RandomIt >
void nth_element( ExecutionPolicy&& policy,
RandomIt first, RandomIt nth, RandomIt last );

(since C++17)

template< class RandomIt, class Compare >
void nth_element( RandomIt first, RandomIt nth, RandomIt last,
Compare comp );

(constexpr since C++20)

template< class ExecutionPolicy, class RandomIt, class Compare >
void nth_element( ExecutionPolicy&& policy,
RandomIt first, RandomIt nth, RandomIt last,
Compare comp );

(since C++17)

# Parameters

# Notes

The algorithm used is typically Introselect although other Selection algorithm with suitable average-case complexity are allowed.

# Example

#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);
}

# Defect reports

DRApplied toBehavior as publishedCorrect behavior
LWG 2150C++98after the rearrangement, only one element before nthwas required to be not greater than one element after nthcorrected therequirement
LWG 2163C++98overload (1) used operator> to compare the elementschanged to operator<
P0896R4C++98[first, nth) and [nth, last)were not required to be valid rangesthe behavior is undefinedif any of them is invalid

# See also