Namensräume
Varianten
Aktionen

std::ranges::stable_sort

Von cppreference.com
< cpp‎ | algorithm‎ | ranges
 
 
Algorithmenbibliothek
Beschränkte Algorithmen und Algorithmen für Bereiche (C++20)
Beschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Ausführungsrichtlinien (C++17)
Nicht-modifizierende Sequenzoperationen
Stapeloperationen
(C++17)
Suchoperationen
(C++11)                (C++11)(C++11)

Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
Ordnungsändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Zusammenführungsoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikographische Vergleichsoperationen
Permutationsoperationen
C-Bibliothek
Numerische Operationen
Operationen auf uninitialisiertem Speicher
 
Eingeschränkte Algorithmen
Alle Namen in diesem Menü gehören zum Namespace std::ranges
Nicht-modifizierende Sequenzoperationen
Modifizierende Sequenzoperationen
Partitionierungsoperationen
Sortieroperationen
stable_sort
       
Binäre Suchoperationen (auf sortierten Bereichen)
       
       
Mengenoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
       
       
Permutationsoperationen
Faltoperationen
Operationen auf uninitialisiertem Speicher
Rückgabetypen
 
Definiert in Header <algorithm>
Aufruf-Signatur
template< std::random_access_iterator I, std::sentinel_for<I> S,

          class Comp = ranges::less, class Proj = std::identity >
erfordert std::sortable<I, Comp, Proj>

    I stable_sort( I first, S last, Comp comp = {}, Proj proj = {} );
(1) (seit C++20)
(constexpr seit C++26)
template< ranges::random_access_range R, class Comp = ranges::less,

          class Proj = std::identity >
erfordert std::sortable<ranges::iterator_t<R>, Comp, Proj>
ranges::borrowed_iterator_t<R>

    stable_sort( R&& r, Comp comp = {}, Proj proj = {} );
(2) (seit C++20)
(constexpr seit C++26)

Sortiert die Elemente im Bereich [firstlast) in nicht absteigender Reihenfolge. Die Reihenfolge äquivalenter Elemente ist stabil, d.h. ihre Beibehaltung ist garantiert.

Eine Sequenz ist in Bezug auf einen Comparator comp sortiert, wenn für jeden Iterator it, der auf die Sequenz zeigt, und jede nicht-negative ganze Zahl n, für die it + n ein gültiger Iterator ist, der auf ein Element der Sequenz zeigt, std::invoke(comp, std::invoke(proj, *(it + n)), std::invoke(proj, *it) zu false ausgewertet wird.

1) Elemente werden mit der gegebenen binären Vergleichsfunktion comp verglichen.
2) Dasselbe wie (1), verwendet aber r als Bereich, als ob ranges::begin(r) als first und ranges::end(r) als last verwendet würden.

Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithmus-Funktionsobjekte (informell als niebloids bekannt), d.h.

Inhalt

[bearbeiten] Parameter

first, last - das Iterator-Sentinel-Paar, das den Bereich der zu sortierenden Elemente definiert
r - der zu sortierende Bereich
comp - Vergleich, der auf die projizierten Elemente angewendet wird
proj - Projektion, die auf die Elemente angewendet wird

[bearbeiten] Rückgabewert

Ein Iterator, der gleich last ist.

[bearbeiten] Komplexität

N·log(N) Vergleiche, wenn zusätzlicher Speicher verfügbar ist; wobei N ranges::distance(first, last) ist. N·log²(N) Vergleiche sonst. In beiden Fällen doppelt so viele Projektionen wie Vergleiche.

[bearbeiten] Hinweise

Feature-Test-Makro Wert Std Feature
__cpp_lib_constexpr_algorithms 202306L (C++26) constexpr stabile Sortierung

[bearbeiten] Mögliche Implementierung

Diese Implementierung zeigt nur den langsameren Algorithmus, der verwendet wird, wenn kein zusätzlicher Speicher verfügbar ist. Siehe auch Implementierungen in MSVC STL und libstdc++.

struct stable_sort_fn
{
    template<std::random_access_iterator I, std::sentinel_for<I> S,
             class Comp = ranges::less, class Proj = std::identity>
    requires std::sortable<I, Comp, Proj>
    constexpr //< since C++26
    I operator()(I first, S last, Comp comp = {}, Proj proj = {}) const
    {
        auto count = ranges::distance(first, last);
        auto mid = first + count / 2;
        auto last_it = first + count;
 
        if (count <= 1)
            return last_it;
 
        (*this)(first, mid, std::ref(comp), std::ref(proj));
        (*this)(mid, last_it, std::ref(comp), std::ref(proj));
 
        ranges::inplace_merge(first, mid, last_it);
 
        return last_it;
    }
 
    template<ranges::random_access_range R, class Comp = ranges::less,
             class Proj = std::identity>
    requires std::sortable<ranges::iterator_t<R>, Comp, Proj>
    constexpr //< since C++26
    ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), std::move(comp), std::move(proj));
    }
};
 
inline constexpr stable_sort_fn stable_sort{};

[bearbeiten] Beispiel

#include <algorithm>
#include <array>
#include <functional>
#include <iomanip>
#include <iostream>
 
void print(const auto& seq)
{
    for (const auto& elem : seq)
        std::cout << elem << ' ';
    std::cout << '\n';
}
 
struct Particle
{
    std::string name; double mass; // MeV
    friend std::ostream& operator<<(std::ostream& os, const Particle& p)
    {
        return os << '\n' << std::left << std::setw(8) << p.name << " : " << p.mass;
    }
};
 
int main()
{
    std::array s{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
 
    // sort using the default operator<
    std::ranges::stable_sort(s);
    print(s);
 
    // sort using a standard library compare function object
    std::ranges::stable_sort(s, std::ranges::greater());
    print(s);
 
    // sort using a custom function object
    struct
    {
        bool operator()(int a, int b) const { return a < b; }
    } customLess;
    std::ranges::stable_sort(s.begin(), s.end(), customLess);
    print(s);
 
    // sort using a lambda expression
    std::ranges::stable_sort(s, [](int a, int b) { return a > b; });
    print(s);
 
    // sort with projection
    Particle particles[]
    {
        {"Electron", 0.511}, {"Muon", 105.66}, {"Tau", 1776.86},
        {"Positron", 0.511}, {"Proton", 938.27}, {"Neutron", 939.57}
    };
    print(particles);
    std::ranges::stable_sort(particles, {}, &Particle::name); //< sorts by name
    print(particles);
    std::ranges::stable_sort(particles, {}, &Particle::mass); //< sorts by mass
    print(particles);
}

Ausgabe

0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0
 
Electron : 0.511
Muon     : 105.66
Tau      : 1776.86
Positron : 0.511
Proton   : 938.27
Neutron  : 939.57
 
Electron : 0.511
Muon     : 105.66
Neutron  : 939.57
Positron : 0.511
Proton   : 938.27
Tau      : 1776.86
 
Electron : 0.511
Positron : 0.511
Muon     : 105.66
Proton   : 938.27
Neutron  : 939.57
Tau      : 1776.86

[bearbeiten] Siehe auch

Sortiert einen Bereich aufsteigend
(Algorithmus-Funktionsobjekt)[edit]
Sortiert die ersten N Elemente eines Bereichs
(Algorithmus-Funktionsobjekt)[edit]
Teilt Elemente in zwei Gruppen auf und behält dabei ihre relative Reihenfolge bei
(Algorithmus-Funktionsobjekt)[edit]
Sortiert einen Bereich von Elementen und behält dabei die Reihenfolge zwischen gleichen Elementen bei
(Funktionstemplate) [edit]