std::nth_element in C++

26 Jul, 2017
std::nth_element() is an STL algorithm which rearranges the list in such a way such that the element at the nth position is the one which should be at that position if we sort the list.
It does not sort the list, just that all the elements, which precede the nth element are not greater than it, and all the elements which succeed it are not less than it.It has two versions, which are defined below:
Comparing elements using “<":Syntax:template 
void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
                  RandomAccessIterator last);

first: Random-access iterator to the first element in the list.
last: Random-access iterator to the last element in the list.
nth: Random-access iterator pointing to the position in the list, 
which should be sorted.
If it points to end, then this function will do nothing.

Return Value: Since, return type is void, so it doesnot return any value.
// C++ program to demonstrate the use of std::nth_element#include <iostream>#include <algorithm>using namespace std;int main(){    int v[] = { 3, 2, 10, 45, 33, 56, 23, 47 }, i;      // Using std::nth_element with n as 5    std::nth_element(v, v + 4, v + 8);      // Since, n is 5 so 5th element should be sorted    for (i = 0; i < 8; ++i) {        cout << v[i] << " ";    }    return 0;}Output:3 2 10 23 33 56 45 47 
Here, the fifth element is 33, and all elements to its left are smaller than it and all elements to its right are greater than it.By comparing using a pre-defined function:Syntax:template 
void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
                  RandomAccessIterator last, Compare comp);

Here, first, last and nth arguments are the same as previous case.

comp: Binary function that accepts two elements in the range 
as arguments, and returns a value convertible to bool.
The value returned indicates whether the element passed as first argument is 
considered to go before the second in the specific strict weak ordering it defines.
The function shall not modify any of its arguments.
This can either be a function pointer or a function object.

Return Value: Since, its return type is void, so it doesnot return any value.
// C++ program to demonstrate the use of std::nth_element#include <iostream>#include <algorithm>using namespace std;  // Defining the BinaryFunctionbool comp(int a, int b){    return (a < b);}int main(){    int v[] = { 3, 2, 10, 45, 33, 56, 23, 47 }, i;      // Using std::nth_element with n as 6    std::nth_element(v, v + 5, v + 8, comp);      // Since, n is 6 so 6th element should be the same    // as the sixth element present if we sort this array    // Sorted Array    /* 2 3 10 23 33 45 47 56 */    for (i = 0; i < 8; ++i) {        cout << v[i] << " ";    }    return 0;}Output:33 2 10 23 3 45 47 56 
In this code, since the nth element as pointed by the second argument in std::nth_element is the sixth element of the array v, so this means that the sixth element in the array after application of std::nth_element should be the one that would have been there if the whole array was sorted, i.e., 45.And also all the element to its left are either less than it or equal to it and elements on its right are greater than it.Purpose of Binary Function comp: std::nth_element partially sorts the range [first, last) in ascending order so that the condition, *i < *j, (for version 1 ), or comp(*i, *j) == true (for version 2) is met for any i in the range [first, nth) and for any j in the range [nth, last). So, comp() is used to ensure that all the elements before the nth_element are less than elements after the nth_element.
Comparing elements using “<":Syntax:template 
void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
                  RandomAccessIterator last);

first: Random-access iterator to the first element in the list.
last: Random-access iterator to the last element in the list.
nth: Random-access iterator pointing to the position in the list, 
which should be sorted.
If it points to end, then this function will do nothing.

Return Value: Since, return type is void, so it doesnot return any value.
// C++ program to demonstrate the use of std::nth_element#include <iostream>#include <algorithm>using namespace std;int main(){    int v[] = { 3, 2, 10, 45, 33, 56, 23, 47 }, i;      // Using std::nth_element with n as 5    std::nth_element(v, v + 4, v + 8);      // Since, n is 5 so 5th element should be sorted    for (i = 0; i < 8; ++i) {        cout << v[i] << " ";    }    return 0;}Output:3 2 10 23 33 56 45 47 
Here, the fifth element is 33, and all elements to its left are smaller than it and all elements to its right are greater than it.
template 
void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
                  RandomAccessIterator last);

first: Random-access iterator to the first element in the list.
last: Random-access iterator to the last element in the list.
nth: Random-access iterator pointing to the position in the list, 
which should be sorted.
If it points to end, then this function will do nothing.

Return Value: Since, return type is void, so it doesnot return any value.

// C++ program to demonstrate the use of std::nth_element#include <iostream>#include <algorithm>using namespace std;int main(){    int v[] = { 3, 2, 10, 45, 33, 56, 23, 47 }, i;      // Using std::nth_element with n as 5    std::nth_element(v, v + 4, v + 8);      // Since, n is 5 so 5th element should be sorted    for (i = 0; i < 8; ++i) {        cout << v[i] << " ";    }    return 0;}
Output:
3 2 10 23 33 56 45 47 

Here, the fifth element is 33, and all elements to its left are smaller than it and all elements to its right are greater than it.
By comparing using a pre-defined function:Syntax:template 
void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
                  RandomAccessIterator last, Compare comp);

Here, first, last and nth arguments are the same as previous case.

comp: Binary function that accepts two elements in the range 
as arguments, and returns a value convertible to bool.
The value returned indicates whether the element passed as first argument is 
considered to go before the second in the specific strict weak ordering it defines.
The function shall not modify any of its arguments.
This can either be a function pointer or a function object.

Return Value: Since, its return type is void, so it doesnot return any value.
// C++ program to demonstrate the use of std::nth_element#include <iostream>#include <algorithm>using namespace std;  // Defining the BinaryFunctionbool comp(int a, int b){    return (a < b);}int main(){    int v[] = { 3, 2, 10, 45, 33, 56, 23, 47 }, i;      // Using std::nth_element with n as 6    std::nth_element(v, v + 5, v + 8, comp);      // Since, n is 6 so 6th element should be the same    // as the sixth element present if we sort this array    // Sorted Array    /* 2 3 10 23 33 45 47 56 */    for (i = 0; i < 8; ++i) {        cout << v[i] << " ";    }    return 0;}Output:33 2 10 23 3 45 47 56 
In this code, since the nth element as pointed by the second argument in std::nth_element is the sixth element of the array v, so this means that the sixth element in the array after application of std::nth_element should be the one that would have been there if the whole array was sorted, i.e., 45.And also all the element to its left are either less than it or equal to it and elements on its right are greater than it.Purpose of Binary Function comp: std::nth_element partially sorts the range [first, last) in ascending order so that the condition, *i < *j, (for version 1 ), or comp(*i, *j) == true (for version 2) is met for any i in the range [first, nth) and for any j in the range [nth, last). So, comp() is used to ensure that all the elements before the nth_element are less than elements after the nth_element.
Syntax:
template 
void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
                  RandomAccessIterator last, Compare comp);

Here, first, last and nth arguments are the same as previous case.

comp: Binary function that accepts two elements in the range 
as arguments, and returns a value convertible to bool.
The value returned indicates whether the element passed as first argument is 
considered to go before the second in the specific strict weak ordering it defines.
The function shall not modify any of its arguments.
This can either be a function pointer or a function object.

Return Value: Since, its return type is void, so it doesnot return any value.

// C++ program to demonstrate the use of std::nth_element#include <iostream>#include <algorithm>using namespace std;  // Defining the BinaryFunctionbool comp(int a, int b){    return (a < b);}int main(){    int v[] = { 3, 2, 10, 45, 33, 56, 23, 47 }, i;      // Using std::nth_element with n as 6    std::nth_element(v, v + 5, v + 8, comp);      // Since, n is 6 so 6th element should be the same    // as the sixth element present if we sort this array    // Sorted Array    /* 2 3 10 23 33 45 47 56 */    for (i = 0; i < 8; ++i) {        cout << v[i] << " ";    }    return 0;}
Output:
33 2 10 23 3 45 47 56 

In this code, since the nth element as pointed by the second argument in std::nth_element is the sixth element of the array v, so this means that the sixth element in the array after application of std::nth_element should be the one that would have been there if the whole array was sorted, i.e., 45.
And also all the element to its left are either less than it or equal to it and elements on its right are greater than it.
Purpose of Binary Function comp: std::nth_element partially sorts the range [first, last) in ascending order so that the condition, *i < *j, (for version 1 ), or comp(*i, *j) == true (for version 2) is met for any i in the range [first, nth) and for any j in the range [nth, last). So, comp() is used to ensure that all the elements before the nth_element are less than elements after the nth_element.
Where can we apply std::nth_element() ?
It can be used if we want to find the first n smallest numbers, but they may or maynot be ordered.// C++ program to find first n smallest numbers#include <iostream>#include <algorithm>using namespace std;int main(){    int v[] = { 30, 20, 10, 40, 60, 50, 70, 80 }, i;      // Using std::nth_element with n as 3    std::nth_element(v, v + 2, v + 8);      // Since, n is 3 so now first three numbers will be the    // three smallest numbers in the whole array    // Displaying first three smallest number    for (i = 0; i < 3; ++i)     {        cout << v[i] << " ";    }    return 0;}Output:20 10 30
Just like first n smallest number, we can also find first n largest numbers, by just changing the Binary Function passed as argument in std::nth_element.// C++ program to find first n largest numbers#include <iostream>#include <algorithm>using namespace std;int main(){    int v[] = { 30, 20, 50, 60, 70, 10, 80, 40 }, i;      // Using std::nth_element with n as 2    std::nth_element(v, v + 1, v + 8, std::greater<int>());      // Since, n is 2 so first 2 elements will be the largest    // among all the array elements    // Displaying First 2 elements    for (i = 0; i < 2; ++i)     {        cout << v[i] << " ";    }    return 0;}Output:80 70
Here, we have passed greater() as binary function, so now nth element will be the one which should be at the nth place if we sort the given array in descending order, so first n elements will be the first n largest elements.It can be used to find the median of the elements given.// C++ program to find the median of the vector#include <iostream>#include <algorithm>#include <vector>using namespace std;int main(){    vector<int> v = { 3, 2, 10, 45, 33, 56, 23, 47, 60 }, i;      // Using std::nth_element with n as v.size()/2 + 1    std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end());      cout << "The median of the array is " << v[v.size() / 2];      return 0;}Output:The median of the array is 33
Here the sorted array will be 2 3 10 23 33 45 47 56 60, so there are 9 elements and the median will be the middle element, i.e., 5th element : 33.
It can be used if we want to find the first n smallest numbers, but they may or maynot be ordered.// C++ program to find first n smallest numbers#include <iostream>#include <algorithm>using namespace std;int main(){    int v[] = { 30, 20, 10, 40, 60, 50, 70, 80 }, i;      // Using std::nth_element with n as 3    std::nth_element(v, v + 2, v + 8);      // Since, n is 3 so now first three numbers will be the    // three smallest numbers in the whole array    // Displaying first three smallest number    for (i = 0; i < 3; ++i)     {        cout << v[i] << " ";    }    return 0;}Output:20 10 30

// C++ program to find first n smallest numbers#include <iostream>#include <algorithm>using namespace std;int main(){    int v[] = { 30, 20, 10, 40, 60, 50, 70, 80 }, i;      // Using std::nth_element with n as 3    std::nth_element(v, v + 2, v + 8);      // Since, n is 3 so now first three numbers will be the    // three smallest numbers in the whole array    // Displaying first three smallest number    for (i = 0; i < 3; ++i)     {        cout << v[i] << " ";    }    return 0;}
Output:
20 10 30

Just like first n smallest number, we can also find first n largest numbers, by just changing the Binary Function passed as argument in std::nth_element.// C++ program to find first n largest numbers#include <iostream>#include <algorithm>using namespace std;int main(){    int v[] = { 30, 20, 50, 60, 70, 10, 80, 40 }, i;      // Using std::nth_element with n as 2    std::nth_element(v, v + 1, v + 8, std::greater<int>());      // Since, n is 2 so first 2 elements will be the largest    // among all the array elements    // Displaying First 2 elements    for (i = 0; i < 2; ++i)     {        cout << v[i] << " ";    }    return 0;}Output:80 70
Here, we have passed greater() as binary function, so now nth element will be the one which should be at the nth place if we sort the given array in descending order, so first n elements will be the first n largest elements.
// C++ program to find first n largest numbers#include <iostream>#include <algorithm>using namespace std;int main(){    int v[] = { 30, 20, 50, 60, 70, 10, 80, 40 }, i;      // Using std::nth_element with n as 2    std::nth_element(v, v + 1, v + 8, std::greater<int>());      // Since, n is 2 so first 2 elements will be the largest    // among all the array elements    // Displaying First 2 elements    for (i = 0; i < 2; ++i)     {        cout << v[i] << " ";    }    return 0;}
Output:
80 70

Here, we have passed greater() as binary function, so now nth element will be the one which should be at the nth place if we sort the given array in descending order, so first n elements will be the first n largest elements.
It can be used to find the median of the elements given.// C++ program to find the median of the vector#include <iostream>#include <algorithm>#include <vector>using namespace std;int main(){    vector<int> v = { 3, 2, 10, 45, 33, 56, 23, 47, 60 }, i;      // Using std::nth_element with n as v.size()/2 + 1    std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end());      cout << "The median of the array is " << v[v.size() / 2];      return 0;}Output:The median of the array is 33
Here the sorted array will be 2 3 10 23 33 45 47 56 60, so there are 9 elements and the median will be the middle element, i.e., 5th element : 33.
// C++ program to find the median of the vector#include <iostream>#include <algorithm>#include <vector>using namespace std;int main(){    vector<int> v = { 3, 2, 10, 45, 33, 56, 23, 47, 60 }, i;      // Using std::nth_element with n as v.size()/2 + 1    std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end());      cout << "The median of the array is " << v[v.size() / 2];      return 0;}
Output:
The median of the array is 33

Here the sorted array will be 2 3 10 23 33 45 47 56 60, so there are 9 elements and the median will be the middle element, i.e., 5th element : 33.
Time Complexity of std::nth_element(): O(n), with n being the distance between first and the last.Related Articles:
std::search
std::find
std::find_if, std::find_if_not
std::find_end
std::sort
This article is contributed by Mrigendra Singh. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
cpp-algorithm-library
STL
C++
STL
CPP
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.