Namespaces
Variants

std::partial_sort

cppreference.net에서
 
 
알고리즘 라이브러리
제약된 알고리즘과 범위 기반 알고리즘 (C++20)
제약된 알고리즘, 예: ranges::copy, ranges::sort, ...
정렬 및 관련 연산
분할 연산
(C++11)    

정렬 연산
이진 탐색 연산
(분할된 범위에서)
집합 연산 (정렬된 범위에서)
병합 연산 (정렬된 범위에서)
힙 연산
최소/최대 연산
(C++11)
(C++17)
사전식 비교 연산
순열 연산


 
헤더 <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) 의 첫 번째 middle − first 개 요소가 정렬된([first, last) 가장 작은 요소가 되도록 요소를 재배열합니다.

동일한 요소의 순서는 유지되지 않습니다. 범위 [middle, last) 의 나머지 요소의 순서는 지정되지 않습니다.

1) 요소는 (C++20까지)에 대해 (C++20부터) operator<정렬std::less{}됩니다.3)
요소는 에 대해 정렬됩니다.comp2,4)
(1,3)과 동일하지만 에 따라 실행됩니다.policy 이러한 오버로드는 다음 표현식의 값이
인 경우에만 오버로드 해결에 참여합니다: true(C++20까지)

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(C++20부터)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

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

또는

(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번째 요소를 찾습니다
(함수 템플릿 & 알고리즘 함수 객체)
요소의 범위를 복사하고 부분 정렬합니다
(함수 템플릿 & 알고리즘 함수 객체)
동등한 요소 간의 상대적 순서를 유지하면서 요소의 범위를 정렬합니다
(함수 템플릿 & 알고리즘 함수 객체)
요소의 범위를 정렬합니다
(함수 템플릿 & 알고리즘 함수 객체)
범위의 처음 N개 요소를 정렬합니다
(알고리즘 함수 객체)