Namespaces
Variants

std:: partial_sort

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
헤더 파일에 정의됨 <algorithm>
template < class RandomIt >
void partial_sort ( RandomIt first, RandomIt middle, RandomIt last ) ;
(1) (C++20부터 constexpr)
template < class ExecutionPolicy, class RandomIt >

void partial_sort ( ExecutionPolicy && policy,

RandomIt first, RandomIt middle, RandomIt last ) ;
(2) (C++17부터)
template < class RandomIt, class Compare >

void partial_sort ( RandomIt first, RandomIt middle, RandomIt last,

Compare comp ) ;
(3) (C++20부터 constexpr)
template < class ExecutionPolicy, class RandomIt, class Compare >

void partial_sort ( ExecutionPolicy && policy,
RandomIt first, RandomIt middle, RandomIt last,

Compare comp ) ;
(4) (C++17부터)

요소들을 재배열하여 [ first , middle ) 범위가 [ first , last ) 범위에서 가장 작은 middle − first 개의 요소를 정렬된 상태로 포함하도록 합니다.

동일한 요소들의 순서는 보존된다고 보장되지 않습니다. 범위 [ middle , last ) 내 남은 요소들의 순서는 명시되지 않습니다.

1) 요소들은 정렬되어 있습니다 operator < (C++20 이전) std:: less { } (C++20 이후) .
3) 요소들은 comp 를 기준으로 정렬됩니다.
2,4) (1,3) 와 동일하지만, policy 에 따라 실행됩니다.
다음 모든 조건이 만족될 때만 이 오버로드들이 오버로드 해결에 참여합니다:

std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> true 인 경우.

(C++20 이전)

std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> true 인 경우.

(C++20 이후)

다음 조건 중 하나라도 충족되면, 동작은 정의되지 않습니다:

  • [ first , middle ) 또는 [ middle , last ) 가 유효한 범위가 아닙니다.
(C++11 이전)
(C++11 이후)

목차

매개변수

first, last - 요소들을 재배열할 범위 를 정의하는 반복자 쌍
middle - [ first , middle ) 범위가 정렬된 요소들을 포함하게 됨
policy - 사용할 실행 정책
comp - 비교 함수 객체 (즉, Compare 요구사항을 만족하는 객체)로, 첫 번째 인수가 두 번째 인수보다 작은 경우 (즉, 순서상 앞서는 경우) ​ true 를 반환함.

비교 함수의 시그니처는 다음에 부합해야 함:

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

시그니처에 const & 가 필요하지는 않지만, 함수는 전달된 객체를 수정해서는 안 되며, 값 범주 에 관계없이 (가능하다면 const인) Type1 Type2 타입의 모든 값을 수용할 수 있어야 함 (따라서 Type1& 는 허용되지 않으며 , Type1 Type1 에 대해 이동이 복사와 동등하지 않는 한 허용되지 않음 (C++11부터) ).
Type1 Type2 타입은 RandomIt 타입의 객체가 역참조된 후 두 타입 모두로 암시적으로 변환 가능해야 함. ​

타입 요구사항
-
RandomIt LegacyRandomAccessIterator 요구사항을 충족해야 함.
-
Compare Compare 요구사항을 충족해야 함.

복잡도

주어진 M middle - first 로, N last - first 로:

1,2) N·log(M) 번의 비교를 사용하며 operator < (C++20 이전) std:: less { } (C++20 이후) .
3,4) N·log(M) 회의 비교자 comp 적용.

예외

ExecutionPolicy 라는 템플릿 매개변수를 사용하는 오버로드는 다음과 같이 오류를 보고합니다:

  • 알고리즘의 일부로 호출된 함수 실행 중 예외가 발생하고 ExecutionPolicy 표준 정책 중 하나인 경우, std::terminate 가 호출됩니다. 다른 ExecutionPolicy 의 경우 동작은 구현에 따라 정의됩니다.
  • 알고리즘이 메모리 할당에 실패하는 경우, std::bad_alloc 이 throw됩니다.

가능한 구현

다음 구현들도 참조하십시오: libstdc++ 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);
}

참고 사항

알고리즘

사용된 알고리즘은 일반적으로 heap select 로 가장 작은 요소들을 선택하고, heap sort 로 힙 내에서 선택된 요소들을 오름차순으로 정렬합니다.

요소를 선택하기 위해 힙이 사용됩니다( heap 참조). 예를 들어, operator < 를 비교 함수로 사용할 경우, max-heap middle − first 개의 가장 작은 요소들을 선택하는 데 사용됩니다.

힙 정렬 은 선택 후에 [ first , middle ) 범위의 선택된 요소들을 정렬하는 데 사용됩니다(참조: std::sort_heap ).

사용 목적

std::partial_sort 알고리즘은 작은 상수 개수 [ first , middle ) 선택된 요소들에 사용되도록 설계되었습니다.

예제

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

가능한 출력:

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

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
P0896R4 C++98 [ first , middle ) [ middle , last )
가 유효한 범위일 필요가 없었음
해당 범위 중 하나라도 유효하지 않으면
동작이 정의되지 않음

참고 항목

주어진 범위를 부분 정렬하여 특정 요소를 기준으로 분할되도록 보장합니다
(함수 템플릿)
요소 범위를 복사하고 부분적으로 정렬합니다
(함수 템플릿)
동일한 요소들 간의 순서를 유지하면서 범위를 정렬합니다
(함수 템플릿)
범위를 오름차순으로 정렬합니다
(함수 템플릿)
범위의 처음 N개 요소를 정렬합니다
(알고리즘 함수 객체)