STL容器的排序,支持随机访问的容器vector,deque,string没有sort成员,可调用std::sort排序;list排序调用自带的list::sort。

下面是std::sort函数,有两个版本:

  1. template <class RandomAccessIterator>
  2. void sort ( RandomAccessIterator first, RandomAccessIterator last );
  3. template <class RandomAccessIterator, class Compare>
  4. void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );

sort函数有以下特征:
1. 要求输入一个范围[first, last)
2. 随机迭代器,能用此算法的容器是支持随机访问的容器:vector, deque, string。
3.第一个版本使用operator<进行比较,默认升序排序,第二个版本使用comp做比较.

关于参数comp,comp带两个同类型的参数,如果第一个参数排在第二个参数前面,返回true,否则返回false
它可以是函数指针,也可以是函数对象。函数指针好理解,何谓函数对象?
函数对象(Function Object),是重载了operator()函数的类(或结构体)实例化出来的对象,使用起来像函数,又叫仿函数。

STL本身提供了几个比较函数,下面这些都是仿函数:
less(小于)
greater(大于)
equal_to(等于)
not_equal_to(不相等)
less_equal(小于等于)
greater_equal(大于等于)

当容器元素为内建类型时可以使用,注意使用的格式,要加模版参数(由于是模板类)和后面的(),如下:

  1. sort(vec.begin(), vec.end(), less<int>());

对于复合类型,实现排序方式有3种方法:
1) 重载operator<操作符
2) 写全局的比较函数
3) 写仿函数,重载operator()形式为:bool operator()(const 类名& 参数){…}

下面看看这3种方法的实现:

  1. // 排序元素,比较的对象
  2. struct Person
  3. {
  4. Person(int id, const string& name, int age): id_(id), name_(name), age_(age)
  5. {}
  6. int id_;
  7. string name_;
  8. int age_;
  9. };
  1. // 方式1:重载operator<用于排序时的比较(写在函数体内)
  2. bool operator< (const Person& rt)
  3. {
  4. return this->id_ < rt.id_;
  5. }
  6. // 排序函数写法,默认调用operator<
  7. sort(members.begin(), members.end());
  1. // 方式2:写比较函数
  2. bool CompAge(const Person& pl, const Person& pr)
  3. {
  4. return pl.age_ < pr.age_;
  5. }
  6. // 排序时传入比较函数指针
  7. sort(members.begin(), members.end(), CompAge);
  1. // 方式3:仿函数
  2. struct CompName
  3. {
  4. bool operator()(const Person& pl, const Person& pr)
  5. {
  6. return pl.name_ < pr.name_;
  7. }
  8. };
  9. // 排序时传入函数对象
  10. sort(members.begin(), members.end(), CompName());

用函数对象代替函数指针的优点:
1. 函数对象可以存储中间结果在数据成员中,而函数想要存中间结果须要设全局变量或静态变量,这个是我们不想要的。
2. 在函数对象中编译器可以实现内联调用,从而提升性能。

下面看一个函数对象的扩展应用

  1. // 利用函数对象实现升降排序
  2. struct CompNameEx{
  3. CompNameEx(bool asce) : asce_(asce)
  4. {}
  5. bool operator()(const Person& pl, const Person& pr)
  6. {
  7. return asce_ ? pl.name_ < pr.name_ : pr.name_ < pl.name_;<span style="white-space:pre">   </span>// 《Eff STL》条款21: 永远让比较函数对相等的值返回false
  8. }
  9. private:
  10. bool asce_;
  11. };
  12. // 使用仿函数排序(升降序)
  13. sort(members.begin(), members.end(), CompNameEx(false));
 

注意:如果是指针的容器,比较函数的参数也应是指针。

最新文章

  1. linux进程间通信-共享内存
  2. mysql set names 命令和 mysql 字符编码问题
  3. SSH相关
  4. 制作一个顶部图片可以拉伸放大缩小效果的tableViewHeader
  5. JNI基础概念以及原理-2016.01.11
  6. ORACLE变量定义及使用(另,T-SQL EXISTS的PLSQL替代写法)
  7. (转)Linux下tomcat JVM内存设置步骤
  8. java学习面向对象之异常之二
  9. java 位运算权限管控(转载)
  10. Ansible系列(一):基本配置和使用
  11. c语言——第0次作业
  12. Coursera, Big Data 4, Machine Learning With Big Data (week 3/4/5)
  13. Magento 2 安装数据表
  14. js-事件以及window操作
  15. Ax用Excel导出表的字段属性信息
  16. 翻译:delete语句(已提交到MariaDB官方手册)
  17. 线程安全的CopyOnWriteArrayList介绍
  18. hihocoder Round #c1(hihoCoder太阁最新面经算法竞赛1 )
  19. 深入理解MySQL的并发控制、锁和事务【转】
  20. springboot读取配置文件的顺序

热门文章

  1. DEV Express控件VScorllBar控件使用
  2. cmd启动Oracle服务和监听服务
  3. [办公自动化]如何让excel图表标签中显示最新值数据
  4. 项目实战之poi导出excel
  5. 使用 FFmpeg 处理高质量 GIF 图片
  6. Codeforces Round #363 (Div. 2)E. LRU
  7. luogu 2627 修建草坪
  8. 【POJ 3233】Matrix Power Series
  9. [CF348B]Apple Tree
  10. jquery对所有&lt;input type=&quot;text&quot;的控件赋值