Namespaces
Variants

std::partial_sort

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    
Stapeloperationen
(C++17)
Suchoperationen
Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Erzeugungsoperationen
Entfernungsoperationen
Reihenfolgeändernde Operationen
(bis 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-/Maximumoperationen
(C++11)
(C++17)
Lexikografische Vergleichsoperationen
Permutationsoperationen


 
Definiert in Header <algorithm>
template< class RandomIt >
void partial_sort( RandomIt first, RandomIt middle, RandomIt last );
(1) (constexpr seit C++20)
template< class ExecutionPolicy, class RandomIt >
void partial_sort( ExecutionPolicy&& policy,
                   RandomIt first, RandomIt middle, RandomIt last );
(2) (seit C++17)
template< class RandomIt, class Compare >
void partial_sort( RandomIt first, RandomIt middle, RandomIt last,
                   Compare comp );
(3) (constexpr seit C++20)
template< class ExecutionPolicy, class RandomIt, class Compare >
void partial_sort( ExecutionPolicy&& policy,
                   RandomIt first, RandomIt middle, RandomIt last,
                   Compare comp );
(4) (seit C++17)

Ordnet Elemente so um, dass der Bereich [first, middle) die sortierten middle − first kleinsten Elemente im Bereich [first, last) enthält.

Die Reihenfolge gleicher Elemente wird nicht garantiert beibehalten. Die Reihenfolge der verbleibenden Elemente im Bereich [middle, last) ist unspezifiziert.

1) Elemente werden bezüglich sortiert operator<(bis C++20)std::less{}(seit C++20).
3) Elemente werden bezüglich comp sortiert.
2,4) 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>>

(bis C++20)

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

(seit C++20)

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

(bis C++11)
(seit C++11)

Parameter

first, last - das Iteratorpaar, das den Bereich der umzuordnenden Elemente definiert
middle - der Bereich [first, middle) wird sortierte Elemente enthalten
policy - die zu verwendende Ausführungsrichtlinie
comp - Vergleichsfunktionsobjekt (d.h. ein Objekt, das die Anforderungen von Compare erfüllt), das ​true zurückgibt, wenn das erste Argument kleiner als (d.h. vor dem zweiten geordnet) ist.

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 ihr ü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 Bewegung äquivalent zu einer Kopie(seit C++11)).
Die Typen Type1 und Type2 müssen so sein, dass ein Objekt vom Typ 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 M als middle - first, N als last - first:

1,2) Etwa N·log(M) Vergleiche unter Verwendung von operator<(bis C++20)std::less{}(seit C++20).
3,4) Etwa N·log(M) Anwendungen des Vergleichsobjekts comp.

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 ausgelöst.

Mögliche Implementierung

Siehe auch die Implementierungen in libstdc++ und libc++.

partial_sort (1)
template<typename RandomIt>
constexpr //< since C++20
void partial_sort(RandomIt first, RandomIt middle, RandomIt last)
{
    typedef typename std::iterator_traits<RandomIt>::value_type VT;
    std::partial_sort(first, middle, last, std::less<VT>());
}
partial_sort (3)
namespace impl
{
    template<typename RandomIt, typename Compare>
    constexpr //< since C++20
    void sift_down(RandomIt first, RandomIt last, const Compare& comp)
    {
        // sift down element at “first”
        const auto length = static_cast<std::size_t>(last - first);
        std::size_t current = 0;
        std::size_t next = 2;
        while (next < length)
        {
            if (comp(*(first + next), *(first + (next - 1))))
                --next;
            if (!comp(*(first + current), *(first + next)))
                return;
            std::iter_swap(first + current, first + next);
            current = next;
            next = 2 * current + 2;
        }
        --next;
        if (next < length && comp(*(first + current), *(first + next)))
            std::iter_swap(first + current, first + next);
    }

    template<typename RandomIt, typename Compare>
    constexpr //< since C++20
    void heap_select(RandomIt first, RandomIt middle, RandomIt last, const Compare& comp)
    {
        std::make_heap(first, middle, comp);
        for (auto i = middle; i != last; ++i)
        {
            if (comp(*i, *first))
            {
                std::iter_swap(first, i);
                sift_down(first, middle, comp);
            }
        }
    }
} // namespace impl

template<typename RandomIt, typename Compare>
constexpr //< since C++20
void partial_sort(RandomIt first, RandomIt middle, RandomIt last, Compare comp)
{
    impl::heap_select(first, middle, last, comp);
    std::sort_heap(first, middle, comp);
}

Hinweise

Algorithmus

Der verwendete Algorithmus ist typischerweise Heap-Auswahl zur Auswahl der kleinsten Elemente und Heap-Sortierung zum Sortieren der ausgewählten Elemente im Heap in aufsteigender Reihenfolge.

Zur Auswahl der Elemente wird ein Heap verwendet (siehe heap). Zum Beispiel wird für operator< als Vergleichsfunktion ein Max-Heap verwendet, um die middle − first kleinsten Elemente auszuwählen.

Heap-Sortierung wird nach der Auswahl verwendet, um die [first, middle) ausgewählten Elemente zu sortieren (siehe std::sort_heap).

Verwendungszweck

std::partial_sort Algorithmen sind für kleine konstante Anzahlen von [first, middle) ausgewählten Elementen vorgesehen.

Beispiel

#include <algorithm>
#include <array>
#include <functional>
#include <iostream>

void print(const auto& s, int middle)
{
    for (int a : s)
        std::cout << a << ' ';
    std::cout << '\n';
    if (middle > 0)
    {
        while (middle-- > 0)
            std::cout << "--";
        std::cout << '^';
    }
    else if (middle < 0)
    {
        for (auto i = s.size() + middle; --i; std::cout << "  ")
        {}
        
        for (std::cout << '^'; middle++ < 0; std::cout << "--")
        {}
    }
    std::cout << '\n';
};

int main()
{
    std::array<int, 10> s{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
    print(s, 0);
    std::partial_sort(s.begin(), s.begin() + 3, s.end());
    print(s, 3);
    std::partial_sort(s.rbegin(), s.rbegin() + 4, s.rend());
    print(s, -4);
    std::partial_sort(s.rbegin(), s.rbegin() + 5, s.rend(), std::greater{});
    print(s, -5);
}

Mögliche Ausgabe:

5 7 4 2 8 6 1 9 0 3

0 1 2 7 8 6 5 9 4 3
------^
4 5 6 7 8 9 3 2 1 0
          ^--------
4 3 2 1 0 5 6 7 8 9
        ^----------

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
P0896R4 C++98 [first, middle) und [middle, last)
mussten keine gültigen Bereiche sein
das Verhalten ist undefiniert
wenn einer von ihnen ungültig ist

Siehe auch

findet das n-te Element, wenn der Bereich sortiert wäre
(Funktionstemplate & Algorithmus-Funktionsobjekt)
kopiert und sortiert einen Bereich von Elementen teilweise
(Funktionstemplate & Algorithmus-Funktionsobjekt)
sortiert einen Bereich von Elementen, wobei die relative Reihenfolge zwischen äquivalenten Elementen erhalten bleibt
(Funktionstemplate & Algorithmus-Funktionsobjekt)
sortiert einen Bereich von Elementen
(Funktionstemplate & Algorithmus-Funktionsobjekt)
sortiert die ersten N Elemente eines Bereichs
(Algorithmus-Funktionsobjekt)