C++ STL 自定义排序总结

C++ 仿函数和自定义排序函数的总结

前置知识(重中之重)

  • 在STL中我们一般有两种自定义排序的方式,一种是对sort的排序规则进行自定义,一种是对STL容器自己的排序规则进行自定义,这两种方式的区别在于:
  1. 对sort函数进行自定义的时候可以使用仿函数(必须是谓词可以使用普通函数
  2. 对STL容器自己的排序规则进行自定义的时候,只能使用仿函数,因为C++的模板编程需要传入模板类型不是函数指针,所以自定义的普通函数在这里是无效的。
  3. 使用仿函数的时候,函数声明后面函数体前面必须加上const,将该函数设置为常量成员函数,表示该函数的隐含this指针被设置为了const指针,即无法在该函数内修改成员变量的值。(只读模式)有关于这一部分可以参照 这里

具体到每一个STL容器的细节

一、map和set

1. 一些基本认识

  • 通常不使用对关联容器使用泛型算法。对于许多需要通过迭代器去修改key的值的泛型算法,关联容器的迭代器不支持这种操作,所以无法使用;而对于一些仅用于访问元素的算法,出于效率考虑,也不推荐使用泛型算法。
  • map和set的单个元素的底层其实都是pair,只不过set的value始终为空,由此可以看出map和set的性质其实基本是一致的。
  • map和set都只能使用key进行排序,如果尝试进行根据value的排序会报错。
  • 由于map和set的底层实现是红黑树,插入的过程中已经做好了排序,所以map和set后期均无法使用sort进行排序。(即,只能在模板中指定其排序的仿函数)

2. 使用仿函数对map排序的具体写法

  • 对一个map<int, int, MyMapSort>key进行降序排序(a>b说明a比b大的时候排在b的前面)

class MyMapSort {
public:
    bool operator() (int a, int b) const {
        return a > b;
    }
};

  • 如何根据value来对map进行排序?(使用vector替代map来存储pair,然后使用sort进行排序)

typedef pair<int, int> Pair;
vector<Pair> v;

class MyVectorSort {
public:
    bool operator() (const Pair& a, const Pair& b) const {
        return a.second > b.second;
    }
};

sort(v.begin(), v.end(), MyVectorSort());

  • 由于vector是可以根据里面装的元素来进行排序的,所以operator()的形参为Pair类型。

  • 从以上写法可以看出来,仿函数实际上是重载了类的operator(),让这个类在外部看来可以跟函数一样使用。STL的模板中也只能将接收这种参数作为自定义排序的手段。

二、vector

1. 一些基本认识

  • vector底层是用数组实现的
  • 支持sort排序

2. 自定义vector的排序的写法

  • 在模板中使用仿函数进行自定义排序:不支持这种操作,底层是数组,也没有办法高效的实现每次插入都排序。

  • 在sort中使用仿函数或者自定义函数进行排序上面已经写过仿函数的,这里来写自定义函数的


typedef pair<int, int> Pair;
vector<Pair> v;

bool myCompare (const Pair& a, const Pair& b) {
    return a.second > b.second;
}

sort(v.begin(), v.end(), myCompare); // 注意这里不需要加括号了,因为传递的是函数指针

posted @ 2022-08-10 22:32  LeisureLak  阅读(658)  评论(0编辑  收藏  举报