std::ranges::sort_heap(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

std::ranges::sort_heap(3) β€” C++ Standard Libary πŸŽ€πŸ’…

okay so you found the std::ranges::sort_heap(3) page from the C++ Standard Libary, and we're gonna make it make sense, bestie ✨

πŸ’– NAME πŸ’–

std::ranges::sort_heap β€” std::ranges::sort_heap πŸ’–

🌸 Synopsis 🌸

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 >
requires std::sortable<I, Comp, Proj>
(1) (since C++20)
constexpr I
    sort_heap( I first, S last, Comp comp = {}, Proj proj = {} );
template< ranges::random_access_range R, class Comp = ranges::less,
          class Proj = std::identity >
(2) (since C++20)
requires std::sortable<ranges::iterator_t<R>, Comp, Proj>
constexpr ranges::borrowed_iterator_t<R>
    sort_heap( R&& r, Comp comp = {}, Proj proj = {} );

Converts the max heap [first, last) into a sorted range in ascending order. The resulting range no longer has the heap property. (periodt, the heap vibe is gone πŸ’€)

  1. Elements are compared using the given binary comparison function comp and projection object proj.
  2. Same as (1), but uses r as the range, as if using ranges::begin(r) as first and ranges::end(r) as last.

Okay so 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. iykyk 🧚

πŸŽ€ Parameters πŸŽ€

  • first, last β€” the range of elements to sort.
  • r β€” the range of elements to sort.
  • pred β€” predicate to apply to the projected elements.
  • proj β€” projection to apply to the elements.

✨ Return value ✨

An iterator equal to last. That's it, that's the return πŸ’…

πŸ”₯ Complexity πŸ”₯

Given N = ranges::distance(first, last), at most 2N log(N) (2Nlog(N)) comparisons and 4N log(N) (4Nlog(N)) projections.

πŸ¦‹ Notes πŸ¦‹

A max heap is a range of elements [f, l), arranged with respect to comparator comp and projection proj, that has the following properties:

  • With N = l - f, p = f[(i - 1) / 2], and q = f[i], for all 0 < i < N, the expression std::invoke(comp, std::invoke(proj, p), std::invoke(proj, q)) evaluates to false.
  • A new element can be added using ranges::push_heap, in O(log N) (π“ž(log N)) time.
  • The first element can be removed using ranges::pop_heap, in O(log N) (π“ž(log N)) time.

πŸ’… 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 {};

🌈 Example 🌈

// Run this code

#include <algorithm>
#include <array>
#include <iostream>

void print(auto const& rem, auto const& 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

πŸ‘€ See also πŸ‘€

  • ranges::is_heap (C++20) (niebloid) β€” checks if the given range is a max heap.
  • ranges::is_heap_until (C++20) (niebloid) β€” finds the largest subrange that is a max heap.
  • ranges::make_heap (C++20) (niebloid) β€” creates a max heap out of a range of elements.
  • ranges::pop_heap (C++20) (niebloid) β€” removes the largest element from a max heap.
  • ranges::push_heap (C++20) (niebloid) β€” adds an element to a max heap.
  • sort_heap (function template) β€” turns a max heap into a range of elements sorted in ascending order.

source: http://cppreference.com Β· version/date: 2024.06.10 Β· page: std::ranges::sort_heap(3) β€” bye bestie, go sort that heap and slay πŸ’–πŸ¦‹βœ¨

πŸ“¦ where this page comes from