Difference between revisions of "cpp/algorithm/ranges/sort heap"
Andreas Krug (Talk | contribs) m (fmt) |
(Wording update.) |
||
(One intermediate revision by one user not shown) | |||
Line 7: | Line 7: | ||
template< std::random_access_iterator I, std::sentinel_for<I> S, | template< std::random_access_iterator I, std::sentinel_for<I> S, | ||
class Comp = ranges::less, class Proj = std::identity > | class Comp = ranges::less, class Proj = std::identity > | ||
− | requires std::sortable<I, Comp, Proj> | + | requires std::sortable<I, Comp, Proj> |
− | constexpr I | + | constexpr I sort_heap( I first, S last, Comp comp = {}, Proj proj = {} ); |
− | + | ||
}} | }} | ||
{{dcl|num=2|since=c++20|1= | {{dcl|num=2|since=c++20|1= | ||
− | template< ranges::random_access_range R, class Comp = ranges::less, | + | template< ranges::random_access_range R, |
− | + | class Comp = ranges::less, class Proj = std::identity > | |
− | requires std::sortable<ranges::iterator_t<R>, Comp, Proj> | + | requires std::sortable<ranges::iterator_t<R>, Comp, Proj> |
constexpr ranges::borrowed_iterator_t<R> | constexpr ranges::borrowed_iterator_t<R> | ||
sort_heap( R&& r, Comp comp = {}, Proj proj = {} ); | sort_heap( R&& r, Comp comp = {}, Proj proj = {} ); | ||
Line 20: | Line 19: | ||
{{dcl end}} | {{dcl end}} | ||
− | + | [[cpp/algorithm#Requirements|Sorts]] the elements in the specified range with respect to {{c|comp}} and {{c|proj}}, where the range originally represents a [[cpp/algorithm#Heap operations|heap]] with respect to {{c|comp}} and {{c|proj}}. The sorted range no longer maintains the heap property. | |
− | @1@ | + | @1@ The specified range is {{range|first|last}}. |
− | @2@ | + | @2@ The specified range is {{c|r}}. |
+ | |||
+ | If the specified range is not a heap with respect to {{c|comp}} and {{c|proj}}, the behavior is undefined. | ||
{{cpp/ranges/niebloid}} | {{cpp/ranges/niebloid}} | ||
Line 30: | Line 31: | ||
===Parameters=== | ===Parameters=== | ||
{{par begin}} | {{par begin}} | ||
− | {{par|first, last|the range of elements to | + | {{par|first, last|the iterator and sentinel designating the range of elements to modify}} |
− | {{par|r|the range of elements to | + | {{par|r|the range of elements to modify}} |
− | {{par| | + | {{par|comp|comparator to apply to the projected elements}} |
{{par|proj|projection to apply to the elements}} | {{par|proj|projection to apply to the elements}} | ||
{{par end}} | {{par end}} | ||
===Return value=== | ===Return value=== | ||
− | + | @1@ {{c|last}} | |
+ | @2@ {{c|ranges::end(r)}} | ||
===Complexity=== | ===Complexity=== | ||
− | + | At most {{mathjax-or|\(\scriptsize 2N \cdot \log(N)\)|2N⋅log(N)}} applications of {{c|comp}} and {{mathjax-or|\(\scriptsize 4N \cdot \log(N)\)|4N⋅log(N)}} applications of {{c|proj}}, where {{mathjax-or|\(\scriptsize N \)|N}} is: | |
− | + | @1@ {{c|ranges::distance(first, last)}} | |
− | + | @2@ {{c|ranges::distance(r)}} | |
− | {{ | + | |
===Possible implementation=== | ===Possible implementation=== | ||
Line 51: | Line 52: | ||
template<std::random_access_iterator I, std::sentinel_for<I> S, | template<std::random_access_iterator I, std::sentinel_for<I> S, | ||
class Comp = ranges::less, class Proj = std::identity> | class Comp = ranges::less, class Proj = std::identity> | ||
− | + | requires std::sortable<I, Comp, Proj> | |
− | constexpr I | + | constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {}) const |
− | + | ||
{ | { | ||
− | auto ret {ranges::next(first, last)}; | + | auto ret{ranges::next(first, last)}; |
for (; first != last; --last) | for (; first != last; --last) | ||
ranges::pop_heap(first, last, comp, proj); | ranges::pop_heap(first, last, comp, proj); | ||
Line 61: | Line 61: | ||
} | } | ||
− | template<ranges::random_access_range R, class Comp = ranges::less, | + | template<ranges::random_access_range R, |
− | + | class Comp = ranges::less, class Proj = std::identity> | |
− | + | requires std::sortable<ranges::iterator_t<R>, Comp, Proj> | |
constexpr ranges::borrowed_iterator_t<R> | constexpr ranges::borrowed_iterator_t<R> | ||
operator()(R&& r, Comp comp = {}, Proj proj = {}) const | operator()(R&& r, Comp comp = {}, Proj proj = {}) const | ||
Line 71: | Line 71: | ||
}; | }; | ||
− | inline constexpr sort_heap_fn sort_heap {}; | + | inline constexpr sort_heap_fn sort_heap{}; |
}} | }} | ||
Line 80: | Line 80: | ||
#include <iostream> | #include <iostream> | ||
− | void print(auto const& rem, | + | void print(auto const& rem, const auto& v) |
{ | { | ||
std::cout << rem; | std::cout << rem; | ||
Line 90: | Line 90: | ||
int main() | int main() | ||
{ | { | ||
− | std::array v {3, 1, 4, 1, 5, 9}; | + | std::array v{3, 1, 4, 1, 5, 9}; |
print("original array: ", v); | print("original array: ", v); | ||
− | + | ||
std::ranges::make_heap(v); | std::ranges::make_heap(v); | ||
print("after make_heap: ", v); | print("after make_heap: ", v); | ||
− | + | ||
std::ranges::sort_heap(v); | std::ranges::sort_heap(v); | ||
print("after sort_heap: ", v); | print("after sort_heap: ", v); |
Latest revision as of 01:41, 15 October 2024
Defined in header <algorithm>
|
||
Call signature |
||
template< std::random_access_iterator I, std::sentinel_for<I> S, class Comp = ranges::less, class Proj = std::identity > |
(1) | (since C++20) |
template< ranges::random_access_range R, class Comp = ranges::less, class Proj = std::identity > |
(2) | (since C++20) |
Sorts the elements in the specified range with respect to comp and proj, where the range originally represents a heap with respect to comp and proj. The sorted range no longer maintains the heap property.
[
first,
last)
.If the specified range is not a heap with respect to comp and proj, the behavior is undefined.
The function-like entities described on this page are niebloids, that is:
- Explicit template argument lists cannot be specified when calling any of them.
- None of them are visible to argument-dependent lookup.
- When any of them are found by normal unqualified lookup as the name to the left of the function-call operator, argument-dependent lookup is inhibited.
In practice, they may be implemented as function objects, or with special compiler extensions.
Contents |
[edit] Parameters
first, last | - | the iterator and sentinel designating the range of elements to modify |
r | - | the range of elements to modify |
comp | - | comparator to apply to the projected elements |
proj | - | projection to apply to the elements |
[edit] Return value
[edit] Complexity
At most 2N⋅log(N) applications of comp and 4N⋅log(N) applications of proj, where N is:
[edit] Possible implementation
struct sort_heap_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 I operator()(I first, S last, Comp comp = {}, Proj proj = {}) const { auto ret{ranges::next(first, last)}; for (; first != last; --last) ranges::pop_heap(first, last, comp, proj); return ret; } template<ranges::random_access_range R, class Comp = ranges::less, class Proj = std::identity> requires std::sortable<ranges::iterator_t<R>, Comp, Proj> constexpr 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 sort_heap_fn sort_heap{}; |
[edit] Example
#include <algorithm> #include <array> #include <iostream> void print(auto const& rem, const auto& v) { std::cout << rem; for (const auto i : v) std::cout << i << ' '; std::cout << '\n'; } int main() { std::array v{3, 1, 4, 1, 5, 9}; print("original array: ", v); std::ranges::make_heap(v); print("after make_heap: ", v); std::ranges::sort_heap(v); print("after sort_heap: ", v); }
Output:
original array: 3 1 4 1 5 9 after make_heap: 9 5 4 1 1 3 after sort_heap: 1 1 3 4 5 9
[edit] See also
(C++20) |
checks if the given range is a max heap (niebloid) |
(C++20) |
finds the largest subrange that is a max heap (niebloid) |
(C++20) |
creates a max heap out of a range of elements (niebloid) |
(C++20) |
removes the largest element from a max heap (niebloid) |
(C++20) |
adds an element to a max heap (niebloid) |
turns a max heap into a range of elements sorted in ascending order (function template) |