Namespaces
Variants

std::ranges:: stable_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
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
Operations on uninitialized storage
Return types
Definido en el encabezado <algorithm>
Firma de llamada
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 >

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

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

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

Ordena los elementos en el rango [ first , last ) en orden no decreciente. El orden de los elementos equivalentes es estable , es decir, se garantiza que se preserve.

Una secuencia está ordenada con respecto a un comparador comp si para cualquier iterador it que apunte a la secuencia y cualquier entero no negativo n tal que it + n sea un iterador válido que apunte a un elemento de la secuencia, std:: invoke ( comp, std:: invoke ( proj, * ( it + n ) ) , std:: invoke ( proj, * it ) evalúa a false .

1) Los elementos se comparan utilizando la función de comparación binaria proporcionada comp .
2) Igual que (1) , pero utiliza r como el rango, como si usara ranges:: begin ( r ) como first y ranges:: end ( r ) como last .

Las entidades similares a funciones descritas en esta página son algorithm function objects (conocidas informalmente como niebloids ), es decir:

Contenidos

Parámetros

first, last - el par iterador-centinela que define el rango de elementos a ordenar
r - el rango a ordenar
comp - comparación a aplicar a los elementos proyectados
proj - proyección a aplicar a los elementos

Valor de retorno

Un iterador igual a last .

Complejidad

N·log(N) comparaciones, si hay memoria adicional disponible; donde N es ranges:: distance ( first, last ) . N·log²(N) comparaciones en caso contrario. El doble de proyecciones que el número de comparaciones en ambos casos.

Notas

Macro de prueba de características Valor Estándar Característica
__cpp_lib_constexpr_algorithms 202306L (C++26) constexpr ordenamiento estable

Implementación posible

Esta implementación solo muestra el algoritmo más lento utilizado cuando no hay memoria adicional disponible. Consulte también la implementación en MSVC STL y 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 //< desde 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 //< desde 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{};

Ejemplo

#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};
    // ordenar usando el operador < por defecto
    std::ranges::stable_sort(s);
    print(s);
    // ordenar usando un objeto función de la biblioteca estándar
    std::ranges::stable_sort(s, std::ranges::greater());
    print(s);
    // ordenar usando un objeto función personalizado
    struct
    {
        bool operator()(int a, int b) const { return a < b; }
    } customLess;
    std::ranges::stable_sort(s.begin(), s.end(), customLess);
    print(s);
    // ordenar usando una expresión lambda
    std::ranges::stable_sort(s, [](int a, int b) { return a > b; });
    print(s);
    // ordenar con proyección
    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); //< ordena por nombre
    print(particles);
    std::ranges::stable_sort(particles, {}, &Particle::mass); //< ordena por masa
    print(particles);
}

Salida:

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

Véase también

ordena un rango en orden ascendente
(objeto función de algoritmo)
ordena los primeros N elementos de un rango
(objeto función de algoritmo)
divide elementos en dos grupos preservando su orden relativo
(objeto función de algoritmo)
ordena un rango de elementos preservando el orden entre elementos iguales
(plantilla de función)