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,
|
(2) | (desde C++17) |
|
template
<
class
RandomIt,
class
Compare
>
void
partial_sort
(
RandomIt first, RandomIt middle, RandomIt last,
|
(3) | (constexpr desde C++20) |
|
template
<
class
ExecutionPolicy,
class
RandomIt,
class
Compare
>
void
partial_sort
(
ExecutionPolicy
&&
policy,
|
(4) | (desde C++17) |
Reorganiza los elementos de modo que el rango
[
first
,
middle
)
contenga los
middle − first
elementos más pequeños ordenados en el rango
[
first
,
last
)
.
El orden de los elementos iguales no está garantizado que se preserve. El orden de los elementos restantes en el rango
[
middle
,
last
)
no está especificado.
|
std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> es true . |
(hasta C++20) |
|
std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> es true . |
(desde C++20) |
Si se satisface cualquiera de las siguientes condiciones, el comportamiento es indefinido:
-
[first,middle)o[middle,last)no es un rango válido .
|
(hasta C++11) |
|
(desde C++11) |
Contenidos |
Parámetros
| first, last | - | el par de iteradores que define el rango de elementos a reorganizar |
| 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 ) ;
Aunque la firma no necesita tener
const
&
, la función no debe modificar los objetos pasados a ella y debe poder aceptar todos los valores de tipo (posiblemente const)
|
| Requisitos de tipo | ||
-
RandomIt
debe cumplir con los requisitos de
LegacyRandomAccessIterator
.
|
||
-
Compare
debe cumplir con los requisitos de
Compare
.
|
||
Complejidad
Dado M como middle - first , N como last - first :
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 uno de los standard policies , std::terminate es llamado. Para cualquier otroExecutionPolicy, el comportamiento está definido por la implementación. - Si el algoritmo falla al asignar memoria, std::bad_alloc es lanzado.
Implementación posible
Consulte 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 heap select para seleccionar los elementos más pequeños, y heap sort para ordenar los elementos seleccionados en el montón en orden ascendente.
Para seleccionar elementos, se utiliza un montículo (consulte heap ). Por ejemplo, para operator < como función de comparación, max-heap se utiliza para seleccionar middle − first elementos más pequeños.
Ordenación por montículos
se utiliza después de la selección para ordenar
[
first
,
middle
)
elementos seleccionados (ver
std::sort_heap
).
Uso previsto
std::partial_sort
los algoritmos están diseñados para ser utilizados con
números constantes pequeños
de elementos seleccionados en el rango
[
first
,
middle
)
.
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); }
Salida posible:
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 de C++ publicados anteriormente.
| DR | Se aplica a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| P0896R4 | C++98 |
[
first
,
middle
)
y
[
middle
,
last
)
no se requería que fueran rangos válidos |
el comportamiento es indefinido
si alguno de ellos es inválido |
Véase también
|
ordena parcialmente el rango dado asegurando que esté particionado por el elemento especificado
(plantilla de función) |
|
|
copia y ordena parcialmente un rango de elementos
(plantilla de función) |
|
|
ordena un rango de elementos preservando el orden entre elementos iguales
(plantilla de función) |
|
|
ordena un rango en orden ascendente
(plantilla de función) |
|
|
(C++20)
|
ordena los primeros N elementos de un rango
(objeto función de algoritmo) |