Namespaces
Variants

std::nth_element

Von de.cppreference.net
 
 
Algorithmenbibliothek
Eingeschränkte Algorithmen und Algorithmen auf Bereichen (C++20)
Eingeschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Nicht modifizierende Sequenzoperationen    
Batch-Operationen
(C++17)
Suchoperationen
Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
Reihenfolgeändernde Operationen
(until C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
(C++11)    

Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Mischoperationen (auf sortierten Bereichen)
Heap-Operationen
Minimum-/Maximum-Operationen
(C++11)
(C++17)
Lexikografische Vergleichsoperationen
Permutationsoperationen


 
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 nth zeigt, wird zu dem Element geändert, das an dieser Position auftreten würde, wenn [first, last) sortiert wäre.
  • Für jeden Iterator i in [first, nth) und jeden Iterator j in [nth, last) ist die folgende Bedingung erfüllt:
1,2) bool(*j < *i)(until C++20)std::less{}(*j, *i)(since C++20) ist false.
3,4) bool(comp(*j, *i)) ist false.


1) Elemente werden hypothetisch sortiert bezüglich operator<(until C++20)std::less{}(since C++20).
3) Elemente werden hypothetisch sortiert bezüglich comp.
2,4) Gleich wie (1,3), aber ausgeführt gemäß policy.
Diese Überladungen nehmen nur an der Überladungsauflösung teil, wenn der Wert des folgenden Ausdrucks true ist:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(until C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(since C++20)

Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:

(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:

bool cmp(const Type1& a, const Type2& b);

Während die Signatur kein const& haben muss, darf die Funktion die übergebenen Objekte nicht modifizieren und muss in der Lage sein, alle Werte des Typs (möglicherweise const) Type1 und Type2 unabhängig von der Wertkategorie zu akzeptieren (daher ist Type1& nicht erlaubt, ebenso wenig Type1, es sei denn, für Type1 ist eine Verschiebung einer Kopie gleichwertig(since C++11)).
Die Typen Type1 und Type2 müssen so sein, dass ein Objekt des Typs RandomIt dereferenziert und dann implizit in beide konvertiert werden kann. ​

Typanforderungen
-
RandomIt muss die Anforderungen von LegacyRandomAccessIterator erfüllen.
-
Compare muss die Anforderungen von Compare erfüllen.

Komplexität

Gegeben N als last - first:

1) O(N) Vergleiche mit operator<(until C++20)std::less{}(since C++20) im Durchschnitt.
2) O(N) Vergleiche mit operator<(until C++20)std::less{}(since C++20), und O(N·log(N)) Vertauschungen.
3) O(N) Anwendungen des Vergleichs comp im Durchschnitt.
4) O(N) Anwendungen des Vergleichs 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 ExecutionPolicy eine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist 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 nth
nicht 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)
gibt das kleinste Element in einem Bereich zurück
(Funktionstemplate & Algorithmusfunktionsobjekt)
kopiert und sortiert teilweise einen Bereich von Elementen
(Funktionstemplate & Algorithmusfunktionsobjekt)
sortiert einen Bereich von Elementen unter Beibehaltung der relativen Reihenfolge zwischen äquivalenten Elementen
(Funktionstemplate & Algorithmusfunktionsobjekt)
sortiert einen Bereich von Elementen
(Funktionstemplate & Algorithmusfunktionsobjekt)
findet das N-te Element, wenn der Bereich sortiert wäre
(Algorithmusfunktionsobjekt)