std::nth_element
| Definiert in Header <algorithm>
|
||
template< class RandomIt >
void nth_element( RandomIt first, RandomIt nth, RandomIt last );
|
(1) | (constexpr since C++20) |
template< class ExecutionPolicy, class RandomIt >
void nth_element( ExecutionPolicy&& policy,
RandomIt first, RandomIt nth, RandomIt last );
|
(2) | (since C++17) |
template< class RandomIt, class Compare >
void nth_element( RandomIt first, RandomIt nth, RandomIt last,
Compare comp );
|
(3) | (constexpr since C++20) |
template< class ExecutionPolicy, class RandomIt, class Compare >
void nth_element( ExecutionPolicy&& policy,
RandomIt first, RandomIt nth, RandomIt last,
Compare comp );
|
(4) | (since C++17) |
nth_element ordnet Elemente in [first, last) so um, dass nach der Umordnung:
- Das Element, auf das
nthzeigt, wird zu dem Element geändert, das an dieser Position auftreten würde, wenn[first,last)sortiert wäre. - Für jeden Iterator
iin[first,nth)und jeden Iteratorjin[nth,last)ist die folgende Bedingung erfüllt:
bool(*j < *i)(until C++20)std::less{}(*j, *i)(since C++20) ist false.bool(comp(*j, *i)) ist false.
comp.policy.true ist:
|
|
(until C++20) |
|
|
(since C++20) |
Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:
[first,nth)oder[nth,last)ist kein gültiger Bereich.
|
(until C++11) |
|
(since C++11) |
Parameter
| first, last | - | das Paar von Iteratoren, das den Bereich der Elemente für die partielle Sortierung definiert |
| nth | - | Random-Access-Iterator, der den Sortierpartitionierungspunkt definiert |
| policy | - | die Ausführungsrichtlinie, die verwendet werden soll |
| comp | - | Vergleichsfunktionsobjekt (d.h. ein Objekt, das die Anforderungen von Compare erfüllt), das true zurückgibt, wenn das erste Argument less als (d.h. vor dem zweiten geordnet ist) das zweite. Die Signatur der Vergleichsfunktion sollte der folgenden entsprechen:
Während die Signatur kein |
| Typanforderungen | ||
-RandomIt muss die Anforderungen von LegacyRandomAccessIterator erfüllen.
| ||
-Compare muss die Anforderungen von Compare erfüllen.
| ||
Komplexität
Gegeben N als last - first:
operator<(until C++20)std::less{}(since C++20) im Durchschnitt.operator<(until C++20)std::less{}(since C++20), und O(N·log(N)) Vertauschungen.comp im Durchschnitt.comp, und O(N·log(N)) Vertauschungen.Ausnahmen
Die Überladungen mit einem Template-Parameter namens ExecutionPolicy melden Fehler wie folgt:
- Wenn die Ausführung einer im Rahmen des Algorithmus aufgerufenen Funktion eine Ausnahme auslöst und
ExecutionPolicyeine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andereExecutionPolicyist das Verhalten implementierungsdefiniert. - Wenn der Algorithmus keinen Speicher zuweisen kann, wird std::bad_alloc geworfen.
Mögliche Implementierung
Siehe auch die Implementierungen in libstdc++, libc++ und MSVC STL.
Anmerkungen
Der verwendete Algorithmus ist typischerweise Introselect, obwohl andere Auswahlalgorithmen mit geeigneter durchschnittlicher Komplexität erlaubt sind.
Beispiel
#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);
}
Mögliche Ausgabe:
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};
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| LWG 2150 | C++98 | nach der Umordnung musste nur ein Element vor nthnicht größer als ein Element nach nth
|
sein, korrigierte die Anforderung |
| LWG 2163 | C++98 | Überladung (1) verwendete operator>, um die Elemente zu vergleichen
|
geändert zu operator<
|
| P0896R4 | C++98 | [first, nth) und [nth, last)mussten keine gültigen Bereiche sein |
das Verhalten ist undefiniert wenn einer davon ungültig ist |
Siehe auch
| gibt das größte Element in einem Bereich zurück (Funktionstemplate & Algorithmusfunktionsobjekt) | |
(C++20) |
|
| gibt das kleinste Element in einem Bereich zurück (Funktionstemplate & Algorithmusfunktionsobjekt) | |
(C++20) |
|
| kopiert und sortiert teilweise einen Bereich von Elementen (Funktionstemplate & Algorithmusfunktionsobjekt) | |
(C++20) |
|
| sortiert einen Bereich von Elementen unter Beibehaltung der relativen Reihenfolge zwischen äquivalenten Elementen (Funktionstemplate & Algorithmusfunktionsobjekt) | |
(C++20) |
|
| sortiert einen Bereich von Elementen (Funktionstemplate & Algorithmusfunktionsobjekt) | |
(C++20) |
|
(C++20) |
findet das N-te Element, wenn der Bereich sortiert wäre (Algorithmusfunktionsobjekt) |