std::partial_sort
| 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.
comp.policy.true:
|
|
(hasta C++20) |
|
|
(desde C++20) |
Si se cumple alguna de las siguientes condiciones, el comportamiento no está definido:
[first,middle)o[middle,last)no es un rango válido.
|
(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:
Si bien la firma no necesita tener |
| 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:
operator<(hasta C++20)std::less{}(desde C++20).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
ExecutionPolicyes una de las políticas estándar, se llama a std::terminate. Para cualquier otroExecutionPolicy, 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) | |
(C++20) |
|
| copia y ordena parcialmente un rango de elementos (plantilla de función & objeto función algoritmo) | |
(C++20) |
|
| ordena un rango de elementos preservando el orden relativo entre elementos equivalentes (plantilla de función & objeto función algoritmo) | |
(C++20) |
|
| ordena un rango de elementos (plantilla de función & objeto función algoritmo) | |
(C++20) |
|
(C++20) |
ordena los primeros N elementos de un rango (objeto función algoritmo) |