Namespaces
Variants

std::partial_sort

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, p. ej. ranges::copy, ranges::sort, ...
Operaciones de secuencia no modificadoras    
Operaciones por lotes
(C++17)
Operaciones de búsqueda
Operaciones de secuencia modificadoras
Operaciones de copia
(C++11)
(C++11)
Operaciones de intercambio
Operaciones de transformación
Operaciones de generación
Operaciones de eliminación
Operaciones de cambio de orden
(hasta C++17)(C++11)
(C++20)(C++20)
Operaciones de muestreo
(C++17)

Operaciones de ordenamiento y relacionadas
Operaciones de particionado
(C++11)    

Operaciones de ordenamiento
Operaciones de búsqueda binaria
(en rangos particionados)
Operaciones de conjuntos (en rangos ordenados)
Operaciones de fusión (en rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
(C++11)
(C++17)
Operaciones de comparación lexicográfica
Operaciones de permutación


 
Definido en el encabezado <algorithm>
template< class RandomIt >
void partial_sort( RandomIt first, RandomIt middle, RandomIt last );
(1) (constexpr desde C++20)
template< class ExecutionPolicy, class RandomIt >
void partial_sort( ExecutionPolicy&& policy,
                   RandomIt first, RandomIt middle, RandomIt last );
(2) (desde C++17)
template< class RandomIt, class Compare >
void partial_sort( RandomIt first, RandomIt middle, RandomIt last,
                   Compare comp );
(3) (constexpr desde C++20)
template< class ExecutionPolicy, class RandomIt, class Compare >
void partial_sort( ExecutionPolicy&& policy,
                   RandomIt first, RandomIt middle, RandomIt last,
                   Compare comp );
(4) (desde C++17)

Reordena los elementos de modo que el rango [first, middle) contenga los middle − first elementos más pequeños ordenados en el rango [first, last).

No se garantiza que se conserve el orden de los elementos iguales. El orden de los elementos restantes en el rango [middle, last) no está especificado.

1) Los elementos se ordenan con respecto a operator<(hasta C++20)std::less{}(desde C++20).
3) Los elementos se ordenan con respecto a comp.
2,4) Igual que (1,3), pero ejecutado según policy.
Estas sobrecargas participan en la resolución de sobrecargas solo si el valor de la siguiente expresión es true:

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

(hasta C++20)

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

(desde C++20)

Si se cumple alguna de las siguientes condiciones, el comportamiento no está definido:

(hasta C++11)
(desde C++11)

Parámetros

first, last - el par de iteradores que definen el rango de elementos a reordenar
middle - el rango [first, middle) contendrá elementos ordenados
policy - la política de ejecución a utilizar
comp - objeto función de comparación (es decir, un objeto que satisface los requisitos de Compare) que devuelve ​true si el primer argumento es menor que (es decir, está ordenado antes) que el segundo.

La firma de la función de comparación debe ser equivalente a la siguiente:

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

Si bien la firma no necesita tener const&, la función no debe modificar los objetos que se le pasan y debe poder aceptar todos los valores de tipo (posiblemente const) Type1 y Type2 independientemente de la categoría de valor (por lo tanto, Type1& no está permitido, como tampoco lo está Type1 a menos que para Type1 un movimiento sea equivalente a una copia(desde C++11)).
Los tipos Type1 y Type2 deben ser tales que un objeto de tipo RandomIt pueda ser desreferenciado y luego convertido implícitamente a ambos. ​

Requisitos de tipo
-
RandomIt debe cumplir los requisitos de LegacyRandomAccessIterator.
-
Compare debe cumplir los requisitos de Compare.

Complejidad

Dado M como middle - first, N como last - first:

1,2) Aproximadamente N·log(M) comparaciones usando operator<(hasta C++20)std::less{}(desde C++20).
3,4) Aproximadamente N·log(M) aplicaciones del comparador comp.

Excepciones

Las sobrecargas con un parámetro de plantilla llamado ExecutionPolicy reportan errores de la siguiente manera:

  • Si la ejecución de una función invocada como parte del algoritmo lanza una excepción y ExecutionPolicy es una de las políticas estándar, se llama a std::terminate. Para cualquier otro ExecutionPolicy, el comportamiento está definido por la implementación.
  • Si el algoritmo no puede asignar memoria, se lanza std::bad_alloc.

Posible implementación

Véanse también las implementaciones en libstdc++ y 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);
}

Notas

Algoritmo

El algoritmo utilizado es típicamente selección por montículo para seleccionar los elementos más pequeños, y ordenamiento por montículo para ordenar los elementos seleccionados en el montículo en orden ascendente.

Para seleccionar elementos, se utiliza un montículo (véase montículo). Por ejemplo, para operator< como función de comparación, se utiliza un max-montículo para seleccionar middle − first elementos más pequeños.

Ordenamiento por montículo se utiliza después de la selección para ordenar los [first, middle) elementos seleccionados (véase std::sort_heap).

Uso previsto

std::partial_sort Los algoritmos están pensados para ser usados con números constantes pequeños de [first, middle) elementos seleccionados.

Ejemplo

#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);
}

Posible salida:

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
        ^----------

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares C++ previamente publicados.

DR Aplicado a Comportamiento publicado Comportamiento correcto
P0896R4 C++98 [first, middle) y [middle, last)
no se requería que fueran rangos válidos
el comportamiento no está definido
si alguno de ellos no es válido

Véase también

encuentra el N-ésimo elemento si el rango estuviera ordenado
(plantilla de función & objeto función algoritmo)
copia y ordena parcialmente un rango de elementos
(plantilla de función & objeto función algoritmo)
ordena un rango de elementos preservando el orden relativo entre elementos equivalentes
(plantilla de función & objeto función algoritmo)
ordena un rango de elementos
(plantilla de función & objeto función algoritmo)
ordena los primeros N elementos de un rango
(objeto función algoritmo)