[STL 20] Algorithm - sorting operation (sort, stable_sort)_set operation (merge)

1. Classification

According to the website https://www.apiref.com/cpp-zh/cpp/header.html , the algorithm provided by the header file <algorithm> is shown in the figure below.

  • Commonly used categories
    • Operations that do not modify the sequence
    • Operations that modify the sequence
    • Sort operation
    • set operation

insert image description here

Second, modify the operation of the sequence

  • Sort operation
Function name usage
sort (first, last) Sort the elements in the range [first, last) in a container or an ordinary array, and sort in ascending order by default.
stable_sort (first, last) Similar to the sort() function, the difference is that for elements with the same value in the [first, last) range, this function will not change their relative positions.
is_sorted (first, last) Check whether the range of [first, last) has been sorted, and check whether it is sorted in ascending order by default.
is_sorted_until() Find the first unsorted element from a sequence.
  • set operation
project Value
merge() Merges two sorted sequences.
inplace_merge() Merges two sorted sequences.

3. Sorting operation

1、sort

The sort() function has 2 usages, and its grammatical formats are:

//对 [first, last) 区域内的元素做默认的升序排序
void sort (RandomAccessIterator first, RandomAccessIterator last);
//按照指定的 comp 排序规则,对 [first, last) 区域内的元素进行排序
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

Among them, both first and last are random access iterators, and their combination [first, last) is used to specify the target area to be sorted; in addition, in the second format, comp can be a sorting rule provided by the C++ STL standard library (such as std::greater), or a custom collation. -

  • demo
#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector
//以普通函数的方式实现自定义排序规则
bool mycomp(int i, int j) {
    
    
    return (i < j);
}
//以函数对象的方式实现自定义排序规则
class mycomp2 {
    
    
public:
    bool operator() (int i, int j) {
    
    
        return (i < j);
    }
};
int main() {
    
    
    std::vector<int> myvector{
    
     10, 1, 3, 5, 7, 9};
    std::cout << "调用第一种语法格式,进行排序:" << std::endl;
    std::sort(myvector.begin(), myvector.begin() + 4); 
    for (auto t : myvector) std::cout << t << ' ';

    std::cout << "\n调用第二种语法格式,利用STL标准库提供的其它比较规则(比如 greater<T>)进行排序:" << std::endl;
    std::sort(myvector.begin(), myvector.begin() + 4, std::greater<int>());
    for (auto t : myvector) std::cout << t << ' ';

    std::cout << "\n调用第二种语法格式,通过自定义比较规则进行排序:" << std::endl;
    std::sort(myvector.begin(), myvector.end(), mycomp2());
    //输出 myvector 容器中的元素
    for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) {
    
    
        std::cout << *it << ' ';
    }
    return 0;
}

2、stable_sort

  • You have seen the function and usage of the sort() function. It is worth mentioning that when the specified range contains multiple equal elements, the sort() sorting function cannot guarantee that their relative positions will not be changed. So, what should you do if you want to complete the sorting and ensure the relative position of equal elements? You can use the stable_sort() function.

  • The stable_sort() function can be regarded as an upgraded version of the sort() function in terms of functionality. In other words, stable_sort() and sort() have the same usage scenarios, and even the grammatical format is the same (will be discussed later), but the former can not only realize the sorting function, but also ensure that the relative value of equal elements will not be changed. Location.

  • There are also two usages of the table_sort() function, and its grammatical format is exactly the same as that of the sort() function (only the function name is different):

//对 [first, last) 区域内的元素做默认的升序排序
void stable_sort ( RandomAccessIterator first, RandomAccessIterator last );
//按照指定的 comp 排序规则,对 [first, last) 区域内的元素进行排序
void stable_sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );

Among them, both first and last are random access iterators, and their combination [first, last) is used to specify the target area to be sorted; in addition, in the second format, comp can be a sorting rule provided by the C++ STL standard library (such as std::greater), or a custom collation.

  • demo
#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector
//以普通函数的方式实现自定义排序规则
bool mycomp(int i, int j) {
    
    
    return (i < j);
}
//以函数对象的方式实现自定义排序规则
class mycomp2 {
    
    
public:
    bool operator() (int i, int j) {
    
    
        return (i < j);
    }
};
int main() {
    
    
    std::vector<int> myvector{
    
     10, 1, 3, 5, 7, 9};
    std::cout << "调用第一种语法格式,进行排序:" << std::endl;
    std::stable_sort(myvector.begin(), myvector.begin() + 4);
    for (auto t : myvector) std::cout << t << ' ';

    std::cout << "\n调用第二种语法格式,利用STL标准库提供的其它比较规则(比如 greater<T>)进行排序:" << std::endl;
    std::stable_sort(myvector.begin(), myvector.begin() + 4, std::greater<int>());
    for (auto t : myvector) std::cout << t << ' ';

    std::cout << "\n调用第二种语法格式,通过自定义比较规则进行排序:" << std::endl;
    std::stable_sort(myvector.begin(), myvector.end(), mycomp2());
    //输出 myvector 容器中的元素
    for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) {
    
    
        std::cout << *it << ' ';
    }
    return 0;
}

output

Call the first grammar format for sorting:
1 3 5 10 7 9
Call the second grammar format and use other comparison rules (such as greater) provided by the STL standard library for sorting:
10 5 3 1 7 9
Call the second grammar format format, sorted by custom comparison rules:
1 3 5 7 9 10

3、is_sorted、is_sorted_until

The is_sorted() function has 2 syntax formats, namely:

//判断 [first, last) 区域内的数据是否符合 std::less<T> 排序规则,即是否为升序序列
bool is_sorted (ForwardIterator first, ForwardIterator last);
//判断 [first, last) 区域内的数据是否符合 comp 排序规则  
bool is_sorted (ForwardIterator first, ForwardIterator last, Compare comp);

Among them, both first and last are forward iterators (which means that this function is applicable to most containers), [first, last) is used to specify the sequence to be detected; comp is used to specify a custom collation.

#include <iostream> 
#include <algorithm>
#include <vector>  
using namespace std;
//以普通函数的方式自定义排序规则
bool mycomp1(int i, int j) {
    
    
    return (i > j);
}
//以函数对象的方式自定义排序规则
class mycomp2 {
    
    
public:
    bool operator() (int i, int j) {
    
    
        return (i > j);
    }
};
int main() {
    
    
    vector<int> myvector{
    
     3,1,2,4 };
    //调用第 2 种语法格式的 is_sorted() 函数,该判断语句会得到执行
    if (!is_sorted(myvector.begin(), myvector.end(), mycomp2())) {
    
    
        cout << "开始对 myvector 容器排序" << endl;
        //对 myvector 容器做降序排序
        sort(myvector.begin(), myvector.end(), mycomp2());
        //输出 myvector 容器中的元素
        for (auto it = myvector.begin(); it != myvector.end(); ++it) {
    
    
            cout << *it << " ";
        }
    }
    return 0;
}

output

Start sorting myvector container
4 3 2 1

  • is_sorted_until

The is_sorted_until() function has the following 2 syntax formats:

//排序规则为默认的升序排序
ForwardIterator is_sorted_until (ForwardIterator first, ForwardIterator last);
//排序规则是自定义的 comp 规则
ForwardIterator is_sorted_until (ForwardIterator first,
                                 ForwardIterator last,
                                 Compare comp);

Among them, both first and last are forward iterators (which means that this function is applicable to most containers), [first, last) is used to specify the sequence to be detected; comp is used to specify a custom collation.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(void) {
    
    
    vector<int> v = {
    
     1, 2, 3, 5, 4 };
    auto it = is_sorted_until(v.begin(), v.end());
    cout << "First unsorted element = " << *it << endl;
    v[3] = 4;
    it = is_sorted_until(v.begin(), v.end());
    if (it == end(v))
        cout << "Entire vector is sorted." << endl;
    return 0;
}

output

First unsorted element = 4
Entire vector is sorted.

4. Set operation

1、merge

The merge() function is used to merge 2 sorted sequences into 1 sorted sequence, provided that the sorting rules of the 2 sorted sequences are the same (either both are in ascending order or both are in descending order). And finally, the new sorted sequence obtained with the help of this function has the same sorting rules as the two sorted sequences.
The developers of the C++ STL standard library considered that users may need to customize the collation, so they designed the following two syntax formats for the merge() function:

//以默认的升序排序作为排序规则
OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
                      InputIterator2 first2, InputIterator2 last2,
                      OutputIterator result);
//以自定义的 comp 规则作为排序规则
OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
                      InputIterator2 first2, InputIterator2 last2,
                      OutputIterator result, Compare comp);

It can be seen that first1, last1, first2, and last2 are all input iterators, [first1, last1) and [first2, last2) are used to specify an ordered sequence; result is an output iterator for the final generated new An ordered sequence specifies the storage location; comp is used to customize the collation. At the same time, the function returns an output iterator that points to the position after the last element in the new sorted sequence.

#include <iostream>     // std::cout
#include <algorithm>    // std::merge
#include <vector>       // std::vector
using namespace std;
int main() {
    
    
    //first 和 second 数组中各存有 1 个有序序列
    int first[] = {
    
     1,3,5,7,9 };
    int second[] = {
    
     2,4,6,8,10 };
    //用于存储新的有序序列
    vector<int> myvector(11);
    //将 [first,first+5) 和 [second,second+5) 合并为 1 个有序序列,并存储到 myvector 容器中。
    merge(first, first + 5, second, second + 5, myvector.begin());
    //输出 myvector 容器中存储的元素
    for (vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) {
    
    
        cout << *it << ' ';
    }
    return 0;
}

2、inplace_merge

When two sorted sequences are stored in the same array or container, if you want to merge them into one sorted sequence, in addition to using the merge() function, it is recommended to use the inplace_merge() function.

Compared with the merge() function, the syntax format of the inplace_merge() function is much simpler:

//默认采用升序的排序规则
void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle,
                    BidirectionalIterator last);
//采用自定义的 comp 排序规则
void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle,
                    BidirectionalIterator last, Compare comp);

Among them, first, middle and last are bidirectional iterators, and [first, middle) and [middle, last) each represent an ordered sequence.

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main(void) {
    
    
   vector<int> v = {
    
    1, 3, 2, 4, 5};
   inplace_merge(v.begin(), v.begin() + 2, v.end());
   for (auto it = v.begin(); it != v.end(); ++it)
      cout << *it << endl;
   return 0;
}

output

1
2
3
4
5

The original plan was to introduce the memory allocator and memory pool in the next two articles, but when combing the knowledge, it was found that the memory model of C++ needs to be clarified to talk about the allocator. Therefore, I will temporarily add a few articles related to the memory model of C++ article.

Reference
1. C++ STL Container Library Chinese Documentation
2. STL Tutorial: C++ STL Quick Start
3. https://www.apiref.com/cpp-zh/cpp/header.html
4. https://en.cppreference.com /w/cpp/header
5. WIKI Tutorial_C++ Standard Library_C++ Library - <algorithm>

Guess you like

Origin blog.csdn.net/junxuezheng/article/details/130021566
Recommended