C++ STL sort

源文件

#include <algorithm>
#include <iostream>
#include <vector>
#include <list>
using namespace std;

/**
 * 表 1 C++ STL 排序函数
函数名	用法
sort (first, last)	对容器或普通数组中 [first, last) 范围内的元素进行排序,默认进行升序排序。
stable_sort (first, last)	和 sort() 函数功能相似,不同之处在于,对于 [first, last) 范围内值相同的元素,该函数不会改变它们的相对位置。
partial_sort (first, middle, last)	从 [first,last) 范围内,筛选出 muddle-first 个最小的元素并排序存放在 [first,middle) 区间中。
partial_sort_copy (first, last, result_first, result_last)	从 [first, last) 范围内筛选出 result_last-result_first 个元素排序并存储到 [result_first, result_last) 指定的范围中。
is_sorted (first, last)	检测 [first, last) 范围内是否已经排好序,默认检测是否按升序排序。
is_sorted_until (first, last)	和 is_sorted() 函数功能类似,唯一的区别在于,如果 [first, last) 范围的元素没有排好序,则该函数会返回一个指向首个不遵循排序规则的元素的迭代器。
void nth_element (first, nth, last)	找到 [first, last) 范围内按照排序规则(默认按照升序排序)应该位于第 nth 个位置处的元素,并将其放置到此位置。同时使该位置左侧的所有元素都比其存放的元素小,该位置右侧的所有元素都比其存放的元素大。
*/

/**
 * sort() 基于快速排序
 * 使用条件:
 * 1.容器支持的迭代器类型必须为随机访问迭代器。这意味着,sort() 只对 array、vector、deque 这 3 个容器提供支持。
 * 2.如果对容器中指定区域的元素做默认升序排序,则元素类型必须支持<小于运算符;同样,如果选用标准库提供的其它排序规则,
    元素类型也必须支持该规则底层实现所用的比较运算符;
 * 3.sort() 函数在实现排序时,需要交换容器中元素的存储位置。这种情况下,如果容器中存储的是自定义的类对象,则该类的内部
    必须提供移动构造函数和移动赋值运算符。
 * 注意:sort()不保证相等元素的相对顺序不变;
*/

/**
 * 语法:
 * 1.//对 [first, last) 区域内的元素做默认的升序排序
    void sort (RandomAccessIterator first, RandomAccessIterator last);
 * 2.//按照指定的 comp 排序规则,对 [first, last) 区域内的元素进行排序
    void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
 * 效率:该函数实现排序的平均时间复杂度为N*log2N(其中 N 为指定区域 [first, last) 中 last 和 first 的距离)。
*/
void printVector(std::vector<int> vec){
    for (auto i = vec.cbegin(); i != vec.cend(); i++)
    {
        std::cout << *i << " " ;
    }
    std::cout << std::endl;
}
bool mycomp(int i, int j){
    return i < j;
}
class mycomp2{
public:
    bool operator() (int i, int j){
        return i < j;
    }
};
class mycomp3{
public:
    bool operator() (int i, int j){
        return i > j;
    }
};
void testSort(){
    std::vector<int> myvector{ 32, 71, 12, 45, 26, 80, 53, 33 };
    //第一种语法,默认升序
    std::sort(myvector.begin(), myvector.end());
    printVector(myvector);
    //第二种语法,stl提供的排序规则
    std::sort(myvector.begin(), myvector.end(), std::greater<int>());
    printVector(myvector);
    //第二种语法,自定义普通函数为排序规则
    std::sort(myvector.begin(), myvector.end(), mycomp);
    printVector(myvector);
    //第二种语法,自定义函数对象为排序规则
    std::sort(myvector.begin(), myvector.end(), mycomp2());
    printVector(myvector);
}
/**
 * stable_sort() 基于归并排序
 * 条件:sort()的前提条件 + 需要相等元素保证相对顺序不变
*/
/**
 * 语法:
 * 1.//对 [first, last) 区域内的元素做默认的升序排序
void stable_sort ( RandomAccessIterator first, RandomAccessIterator last );
 * 2.//按照指定的 comp 排序规则,对 [first, last) 区域内的元素进行排序
void stable_sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );
 * 效率:当可用空间足够的情况下,该函数的时间复杂度可达到O(N*log2(N));
        反之,时间复杂度为O(N*log2(N)2),其中 N 为指定区域 [first, last) 中 last 和 first 的距离。
*/
void testStableSort(){
    std::vector<int> myvector{ 33, 71, 12, 71, 26, 33, 53, 33 };
    //第一种语法,默认升序
    std::stable_sort(myvector.begin(), myvector.end());
    printVector(myvector);
    //第二种语法,stl提供的排序规则
    std::stable_sort(myvector.begin(), myvector.end(), std::greater<int>());
    printVector(myvector);
    //第二种语法,自定义普通函数为排序规则
    std::stable_sort(myvector.begin(), myvector.end(), mycomp);
    printVector(myvector);
    //第二种语法,自定义函数对象为排序规则
    std::stable_sort(myvector.begin(), myvector.end(), mycomp2());
    printVector(myvector);
}

/**
 * partial_sort() 函数会以交换元素存储位置的方式实现部分排序的。具体来说,partial_sort() 会将 [first, last) 范围内最小(或最大)
 的 middle-first 个元素移动到 [first, middle) 区域中,并对这部分元素做升序(或降序)排序。
 * 条件:
 1.容器支持的迭代器类型必须为随机访问迭代器。这意味着,partial_sort() 函数只适用于 array、vector、deque 这 3 个容器。
 2.当选用默认的升序排序规则时,容器中存储的元素类型必须支持 <小于运算符;同样,如果选用标准库提供的其它排序规则,元素类型也必须支持该规则底层实现所用的比较运算符;
 3.partial_sort() 函数在实现过程中,需要交换某些元素的存储位置。因此,如果容器中存储的是自定义的类对象,则该类的内部必须提供移动构造函数和移动赋值运算符。

*/
/**
 * 语法:
 1.//按照默认的升序排序规则,对 [first, last) 范围的数据进行筛选并排序
void partial_sort (RandomAccessIterator first,
                   RandomAccessIterator middle,
                   RandomAccessIterator last);
 2.//按照 comp 排序规则,对 [first, last) 范围的数据进行筛选并排序
void partial_sort (RandomAccessIterator first,
                   RandomAccessIterator middle,
                   RandomAccessIterator last,
                   Compare comp);
 * 效率:partial_sort() 函数实现排序的平均时间复杂度为N*log(M),其中 N 指的是 [first, last) 范围的长度,M 指的是 [first, middle) 范围的长度。 
*/
void partial_sort(){
    std::vector<int> myvector{ 3,2,5,4,1,6,9,7};
    //以默认的升序排序作为排序规则,将 myvector 中最小的 4 个元素移动到开头位置并排好序
    std::partial_sort(myvector.begin(), myvector.begin() + 4, myvector.end());
    std::cout << "第一次排序:\n";
    for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
        std::cout << *it << ' ';
    std::cout << "\n第二次排序:\n";
    // 以指定的 mycomp2 作为排序规则,将 myvector 中最大的 4 个元素移动到开头位置并排好序
    std::partial_sort(myvector.begin(), myvector.begin() + 4, myvector.end(), mycomp3());
    for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
        std::cout << *it << ' ';
}
/**
 * partial_sort_copy() 函数的功能和 partial_sort() 类似,唯一的区别在于,前者不会对原有数据做任何变动,
    而是先将选定的部分元素拷贝到另外指定的数组或容器中,然后再对这部分元素进行排序。
 * partial_sort_copy() 函数会将 [first, last) 范围内最小(或最大)的 result_last-result_first 个元素
    复制到 [result_first, result_last) 区域中,并对该区域的元素做升序(或降序)排序。
*/
/**
 * 语法://默认以升序规则进行部分排序
RandomAccessIterator partial_sort_copy (
                       InputIterator first,
                       InputIterator last,
                       RandomAccessIterator result_first,
                       RandomAccessIterator result_last);
//以 comp 规则进行部分排序
RandomAccessIterator partial_sort_copy (
                       InputIterator first,
                       InputIterator last,
                       RandomAccessIterator result_first,
                       RandomAccessIterator result_last,
                       Compare comp);
 * 效率:partial_sort_copy() 函数实现排序的平均时间复杂度为N*log(min(N,M)),其中 N 指的是 [first, last) 范围的长度,
    M 指的是 [result_first, result_last) 范围的长度。
*/
void partial_sort_copy(){
    int myints[5] = { 0 };
    std::list<int> mylist{ 3,2,5,4,1,6,9,7 };
    //按照默认的排序规则进行部分排序
    std::partial_sort_copy(mylist.begin(), mylist.end(), myints, myints + 5);
    std::cout << "第一次排序:\n";
    for (int i = 0; i < 5; i++) {
        std::cout << myints[i] << " ";
    }
    //以自定义的 mycomp2 作为排序规则,进行部分排序
    std::partial_sort_copy(mylist.begin(), mylist.end(), myints, myints + 5, mycomp3());
    std::cout << "\n第二次排序:\n";
    for (int i = 0; i < 5; i++) {
        std::cout << myints[i] << " ";
    }
}
/**
 * nth_element() 函数的功能,当采用默认的升序排序规则(std::less<T>)时,该函数可以从某个序列中找到第 n 小的元素 K,
  并将 K 移动到序列中第 n 的位置处。不仅如此,整个序列经过 nth_element() 函数处理后,所有位于 K 之前的元素都比 K 小,所有位于 K 之后的元素都比 K 大。
 * 条件:注意,鉴于 nth_element() 函数中各个参数的类型,其只能对普通数组或者部分容器进行排序。换句话说,只有普通数组和符合以下全部条件的容器,才能使用使用 nth_element() 函数:
1.容器支持的迭代器类型必须为随机访问迭代器。这意味着,nth_element() 函数只适用于 array、vector、deque 这 3 个容器。
2.当选用默认的升序排序规则时,容器中存储的元素类型必须支持 <小于运算符;同样,如果选用标准库提供的其它排序规则,元素类型也必须支持该规则底层实现所用的比较运算符;
3.nth_element() 函数在实现过程中,需要交换某些元素的存储位置。因此,如果容器中存储的是自定义的类对象,则该类的内部必须提供移动构造函数和移动赋值运算符。
*/
/**
 * 语法:
 1.//排序规则采用默认的升序排序
void nth_element (RandomAccessIterator first,
                  RandomAccessIterator nth,
                  RandomAccessIterator last);
2.//排序规则为自定义的 comp 排序规则
void nth_element (RandomAccessIterator first,
                  RandomAccessIterator nth,
                  RandomAccessIterator last,
                  Compare comp);
其中,各个参数的含义如下:
first 和 last:都是随机访问迭代器,[first, last) 用于指定该函数的作用范围(即要处理哪些数据);
nth:也是随机访问迭代器,其功能是令函数查找“第 nth 大”的元素,并将其移动到 nth 指向的位置;
comp:用于自定义排序规则。
 * 效率:
*/
void nth_element(){
    std::vector<int> myvector{3,1,2,5,4};
    //默认的升序排序作为排序规则
    std::nth_element(myvector.begin(), myvector.begin()+2, myvector.end());
    std::cout << "第一次nth_element排序:\n";
    for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) {
        std::cout << *it << ' ';
    }
    //自定义的 mycomp2() 或者 mycomp1 降序排序作为排序规则
    std::nth_element(myvector.begin(), myvector.begin() + 3, myvector.end(),mycomp);
    std::cout << "\n第二次nth_element排序:\n";
    for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) {
        std::cout << *it << ' ';
    }
}
/**
 * is_sorted() 判断是否有序
 * 语法:
 1.//判断 [first, last) 区域内的数据是否符合 std::less<T> 排序规则,即是否为升序序列
bool is_sorted (ForwardIterator first, ForwardIterator last);
 2.//判断 [first, last) 区域内的数据是否符合 comp 排序规则  
bool is_sorted (ForwardIterator first, ForwardIterator last, Compare comp);
*/
void is_sorted(){
    vector<int> myvector{ 3,1,2,4 };
    list<int> mylist{ 1,2,3,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 << " ";
        }
    }
   
    //调用第一种语法格式的 is_sorted() 函数,该判断语句得不到执行
    if (!is_sorted(mylist.begin(), mylist.end())) {
        cout << "开始对 mylist 排序" << endl;
        //......
    }
}
/**
 * is_sorted_until() 函数不仅能检测出某个序列是否有序,还会返回一个正向迭代器,该迭代器指向的是当前序列中第一个破坏有序状态的元素。
 * 语法:
1.//排序规则为默认的升序排序
ForwardIterator is_sorted_until (ForwardIterator first, ForwardIterator last);
2.//排序规则是自定义的 comp 规则
ForwardIterator is_sorted_until (ForwardIterator first,
                                 ForwardIterator last,
                                 Compare comp);
其中,first 和 last 都为正向迭代器(这意味着该函数适用于大部分容器),[first, last) 用于指定要检测的序列;comp 用于指定自定义的排序规则。
*/
void is_sorted_until(){
    vector<int> myvector{ 3,1,2,4 };
    list<int> mylist{ 1,2,3,4 };
    //如果返回值为 myvector.end(),则表明 myvector 容器中的序列符合 mycomp2() 规则
    if (is_sorted_until(myvector.begin(), myvector.end(),mycomp2()) != myvector.end()) {
        cout << "开始对 myvector 容器排序" << endl;
        //对 myvector 容器做降序排序
        sort(myvector.begin(), myvector.end(),mycomp2());
        //输出 myvector 容器中的元素
        for (auto it = myvector.begin(); it != myvector.end(); ++it) {
            cout << *it << " ";
        }
    }
   
    //该判断语句得不到执行
    if (is_sorted_until(mylist.begin(), mylist.end()) != mylist.end()) {
        cout << "开始对 mylist 排序" << endl;
        //......
    }
}

int main(){
    // testSort();
    // testStableSort();
    // partial_sort();
    // partial_sort_copy();
    // nth_element();
    // is_sorted();
    is_sorted_until();
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值