Namespaces
Variants

std:: partial_sort

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Definiert im 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 die Elemente so um, dass der Bereich [ first , middle ) die sortierten middle − first kleinsten Elemente im Bereich [ first , last ) enthält.

Die Reihenfolge gleicher Elemente ist nicht garantiert erhalten. Die Reihenfolge der verbleibenden Elemente im Bereich [ middle , last ) ist nicht spezifiziert.

1) Elemente sind sortiert bezüglich operator < (bis C++20) std:: less { } (seit C++20) .
3) Elemente werden bezüglich comp sortiert.
2,4) Gleich wie (1,3) , aber ausgeführt gemäß policy .
Diese Überladungen nehmen nur dann an der Überladungsauflösung teil, wenn alle folgenden Bedingungen erfüllt sind:

std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> ist true .

(bis C++20)

std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> ist true .

(seit C++20)

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

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

Inhaltsverzeichnis

Parameter

first, last - das Paar von Iteratoren, 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) das zweite Argument ist.

Die Signatur der Vergleichsfunktion sollte äquivalent zu Folgendem sein:

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

Obwohl die Signatur nicht const & benötigt, darf die Funktion die übergebenen Objekte nicht modifizieren und muss alle Werte des Typs (möglicherweise const) Type1 und Type2 unabhängig von der Wertkategorie akzeptieren können (daher ist Type1& nicht erlaubt , ebenso wenig wie Type1 , es sei denn, für Type1 ist eine Verschiebung äquivalent zu einer Kopie (seit C++11) ).
Die Typen Type1 und Type2 müssen so beschaffen 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) Ungefähr N·log(M) Vergleiche unter Verwendung von operator < (bis C++20) std:: less { } (seit C++20) .
3,4) Ungefähr N·log(M) Anwendungen des Vergleichsoperators comp .

Ausnahmen

Die Überladungen mit einem Template-Parameter namens ExecutionPolicy melden Fehler wie folgt:

  • Wenn die Ausführung einer als Teil des Algorithmus aufgerufenen Funktion eine Exception wirft und ExecutionPolicy einer der Standard-Policies ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsdefiniert.
  • Wenn der Algorithmus keinen Speicher allokieren kann, wird std::bad_alloc geworfen.

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 select zur Auswahl der kleinsten Elemente und heap sort zum Sortieren der ausgewählten Elemente im Heap in aufsteigender Reihenfolge.

Um Elemente auszuwählen, 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 Sort 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
falls einer von ihnen ungültig ist

Siehe auch

sortiert den gegebenen Bereich teilweise und stellt sicher, dass er durch das gegebene Element partitioniert wird
(Funktions-Template)
kopiert und sortiert einen Bereich von Elementen teilweise
(Funktions-Template)
sortiert einen Bereich von Elementen unter Beibehaltung der Reihenfolge zwischen gleichen Elementen
(Funktions-Template)
sortiert einen Bereich in aufsteigender Reihenfolge
(Funktions-Template)
sortiert die ersten N Elemente eines Bereichs
(Algorithmus-Funktionsobjekt)