본문으로 바로가기

<개요>


이번엔 파티션에 대한 함수들을 다루어보겠습니다. 


<std::partition>


std::partition은 한 기준으로 컨테이너를 좌 또는 우로 나눕니다.

정렬은 되지 않습니다.

기준점이 되는 iterator을 생성하여, 그 iteartor의 좌측은 술어가 참인 값들, 우측은 술어가 거짓인 값들이 모이게 됩니다.

std::partition은 양방향 반복자를 지원합니다.


1
2
3
4
5
6
7
8
9
10
11
12
vector<int> vnt = { 1,2,3,4,5,6,7,8,9,10 };
vector<int>::iterator A = partition(vnt.begin(), vnt.end(), [](int i) {
    return (i % 2 == 0);
});
//10 2 8 4 6 5 7 3 9 1 기준은 '5'
// 만약 기준대로 출력해보고 싶다면?
for (auto i = vnt.begin(); i != A; ++i) {
    cout << *<< endl;
}// 10 2 8 4 6
for (auto i = A; i != vnt.end(); ++i) {
    cout << *<< endl;
}// 5 7 3 9 1
cs

partition 또한 안정적이지 못합니다. ( stable 이 아님 )
복잡도는 ( last - first ) / 2 swap 입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
template <class ForwardIt>
 void quicksort(ForwardIt first, ForwardIt last)
 {
    if(first == last) return;
    auto pivot = *std::next(first, std::distance(first,last)/2);
    ForwardIt middle1 = std::partition(first, last, 
                         [pivot](const auto& em){ return em < pivot; });
    ForwardIt middle2 = std::partition(middle1, last, 
                         [pivot](const auto& em){ return !(pivot < em); });
    quicksort(first, middle1);
    quicksort(middle2, last);
 }
 
int main()
{
    std::vector<int> v = {0,1,2,3,4,5,6,7,8,9};
    std::cout << "Original vector:\n    ";
    for(int elem : v) std::cout << elem << ' ';
 
    auto it = std::partition(v.begin(), v.end(), [](int i){return i % 2 == 0;});
 
    std::cout << "\nPartitioned vector:\n    ";
    std::copy(std::begin(v), it, std::ostream_iterator<int>(std::cout" "));
    std::cout << " * ";
    std::copy(it, std::end(v), std::ostream_iterator<int>(std::cout" "));
 
    std::forward_list<int> fl = {130-435-416-82-564192};
    std::cout << "\nUnsorted list:\n    ";
    for(int n : fl) std::cout << n << ' ';
    std::cout << '\n';  
 
    quicksort(std::begin(fl), std::end(fl));
    std::cout << "Sorted using quicksort:\n    ";
    for(int fi : fl) std::cout << fi << ' ';
    std::cout << '\n';
}
cs
< 퀵 소트의 파티션 예 >


<std::stable_partition>


std::stable_partition 은 위의 partition과 똑같지만, 안정적입니다. 


1
2
3
4
5
vector<int> vnt = { 1,2,3,4,5,6,7,8,9,10 };
vector<int>::iterator A = stable_partition(vnt.begin(), vnt.end(), [](int i) {
    return (i % 2 == 0);
});
//2 4 6 8 10 1 3 5 7 9 기준은 '5'
cs


<std::partition_point>

std::partition_point 는 나뉘어진 파티션에서 술어에 맞지않는 첫번째 반복자를 찾아냅니다.
위의 vector<int>::iterator A 같이 기준점을 찾는데 사용됩니다.

1
2
3
4
5
6
7
8
9
vector<int> vnt = { 1,2,3,4,5,6,7,8,9,10 };
stable_partition(vnt.begin(), vnt.end(), [](int i) {
    return (i % 2 == 0);
});    
//2 4 6 8 10 1 3 5 7 9 기준은 ....?
 
auto point =  partition_point(vnt.begin(), vnt.end(), [](int i) {
    return (i % 2 == 0);
});    // 기준은 1 
cs