sort函数:对于容器等进行排序,头文件位于<algorithm>中。

普通:可以在sort的第三个参数传入

  • 无参:default = less<>()
  • less<>():默认升序
  • greater<>():默认降序

另外,可以通过自定义的方式来设置sort()的比较函数

引用:https://bbs.huaweicloud.com/blogs/detail/312149

方式1:传入自定义函数指针,(有人也称为回调函数)

    bool cmp2(int a, int b) //从大到小
{
return a > b;
}
sort(num, num + 4, cmp2);

方式2:传入一个包含仿函数的对象

引用: https://zhuanlan.zhihu.com/p/362323211

仿函数:定义一个类,类里面定义了某个方法,将该类的对象作为函数的入参,那么在函数中就能调用这个类中的方法。

或者,定义一个类,类里面重载函数运算符(),将该类的对象作为函数的入参,那么在函数中同样能调用重载符()里面的方法

函数对象的出现是为了代替函数指针的,最明显的一个特点是:可以使用内联函数。而如果使用内联函数的指针,编译器会把它当普通函数对待。另外,函数对象是类封装的,代码不但看起来简洁,设计也灵活,比如还可以用关联,聚合,依赖的类之间的关系,与用到他们的类组合在一起,这样有利于资源的管理(这点可能是它相对于函数最显著的优点了)。

仿函数(Functor)也是 STL 六大模块之一,其余 5 个分别是容器(Container)、算法(Algorithm)、迭代器(Iterator)、适配器(Adapter)和分配器(Allocator)。

    class cmp
{
public:
bool operator()(int a, int b) //从小到大
{
return a < b;
}
};
sort(num, num + 4, cmp());

方式3:重载 < 运算符

通常用于自定义数据类型,如结构体和类等。

bool operator< (const Student& s1, const Student& s2)
{
if(s1.age==s2.age)
return s1.name <s2.name;//年龄相同时,按姓名小到大排
else
return s1.age > s2.age; //从年龄大到小排序
}
sort(a,a+n);

方式4:lambda匿名函数

另外,对于规模较小的比较函数,lambda有时是一个更简洁的选择。

	//lambda表达式定义排序规则
sort(ret.begin(), ret.end(),[](pair<int, int >a, pair<int, int >b)
{ if (a.second != b.second) return a.second < b.second; else return a.first < b.first;});

源代码阅读:sort

    template<class _RanIt,
class _Pr> inline
void sort(_RanIt _First, _RanIt _Last, _Pr _Pred)
{ // order [_First, _Last), using _Pred
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Pred);
_Sort(_Unchecked(_First), _Unchecked(_Last), _Last - _First, _Pred);
}
// TEMPLATE FUNCTION sort
template<class _RanIt> inline
void sort(_RanIt _First, _RanIt _Last)
{ // order [_First, _Last), using operator<
_STD sort(_First, _Last, less<>());
}

源代码阅读:_Sort

template<class _RanIt,
class _Diff,
class _Pr> inline
void _Sort(_RanIt _First, _RanIt _Last, _Diff _Ideal, _Pr _Pred)
{ // order [_First, _Last), using _Pred
_Diff _Count;
for (; _ISORT_MAX < (_Count = _Last - _First) && 0 < _Ideal; )
{ // divide and conquer by quicksort
pair<_RanIt, _RanIt> _Mid =
_Unguarded_partition(_First, _Last, _Pred);
_Ideal /= 2, _Ideal += _Ideal / 2; // allow 1.5 log2(N) divisions
if (_Mid.first - _First < _Last - _Mid.second)
{ // loop on second half
_Sort(_First, _Mid.first, _Ideal, _Pred);
_First = _Mid.second;
}
else
{ // loop on first half
_Sort(_Mid.second, _Last, _Ideal, _Pred);
_Last = _Mid.first;
}
}
if (_ISORT_MAX < _Count)
{ // heap sort if too many divisions
_STD make_heap(_First, _Last, _Pred);
_STD sort_heap(_First, _Last, _Pred);
}
else if (1 < _Count)
_Insertion_sort(_First, _Last, _Pred); // small
}

注:以上代码来源于引用链接,但是我看了下MSVC C++ 20下的algorithm代码,除了宏命名以外,基本逻辑没有太大区别。

STL库函数的实现是:快速排序 + 堆排序 + 插入排序

首先调用快排,对于数据进行依据pivot的分割,递归调用,

对于较大的数据(_ISORT_MAX < _Count),建立heap堆排序,

对于较小的数据:插入排序

C++自定义sort比较函数的四种方法的更多相关文章

  1. 织梦DedeCMS模板防盗的四种方法

    织梦(DedeCMS)模板也是一种财富,不想自己辛辛苦苦做的模板被盗用,在互联网上出现一些和自己一模一样的网站,就需要做好模板防盗.本文是No牛收集整理自网络,不过网上的版本都没有提供 Nginx 3 ...

  2. 运行jar应用程序引用其他jar包的四种方法

    转载地址:http://www.iteye.com/topic/332580 大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个ja ...

  3. C#播放声音的四种方法 +AxWindowsMediaPlayer的详细用法

    C#播放声音的四种方法 第一种是利用DirectX 1.安装了DirectX SDK(有9个DLL文件).这里我们只用到MicroSoft.DirectX.dll和 Microsoft.Directx ...

  4. (转载)eclipse插件安装的四种方法

    eclipse插件安装的四种方法 Eclipse插件的安装方法 1.在eclipse的主目录(ECLIPSE_HOME, 比如在我的机器上安装的目录是:D:\eclipse)有一个plugins的目录 ...

  5. iOS-UITextField中给placeholder动态设置颜色的四种方法

    思路分析: 0.自定义UITextField 1.设置占位文字的颜色找-->placeholderColor,结果发现UITextField没有提供这个属性 2.在storyboard/xib中 ...

  6. android中退出当前应用程序的四种方法

    android中退出当前应用程序的四种方法 [IT168 技术]Android程序有很多Activity,比如说主窗口A,调用了子窗口B,如果在B中直接finish(), 接下里显示的是A.在B中如何 ...

  7. Dojo初探之2:设置dojoConfig详解,dojoConfig参数详解+Dojo中预置自定义AMD模块的四种方式(基于dojo1.11.2)

    Dojo中想要加载自定义的AMD模块,需要先设置好这个模块对应的路径,模块的路径就是这个模块的唯一标识符. 一.dojoConfig参数设置详解 var dojoConfig = { baseUrl: ...

  8. mysql insert插入时实现如果数据表中主键重复则更新,没有重复则插入的四种方法

    [CSDN下载] Powerdesigner 设计主键code不能重复等问题 [CSDN博客] Oracle中用一个序列给两个表创建主键自增功能的后果 [CSDN博客] MySQL自增主键删除后重复问 ...

  9. python QQTableView中嵌入复选框CheckBox四种方法

    搜索了一下,QTableView中嵌入复选框CheckBox方法有四种: 第一种不能之前显示,必须双击/选中后才能显示,不适用. 第二种比较简单,通常用这种方法. 第三种只适合静态显示静态数据用 第四 ...

  10. eclipse插件安装的四种方法

    Eclipse插件的安装方法 1.在eclipse的主目录(ECLIPSE_HOME,比如在我的机器上安装的目录是:D:\eclipse)有一个plugins的目录,这种方法的插件安装非常简单,只要将 ...

随机推荐

  1. freeswitch如何判断挂机方

    概述 freeswitch作为VOIP的软交换平台,需要对呼叫的信息做判断和归类. 常见的呼叫信息中,挂机方向的信息对于话单统计有很大的用处. 但是fs的原始话单和日志中并没有挂机方向的信息. 环境 ...

  2. MyBatis 系列:MyBatis 源码环境搭建

    目录 一.环境准备 二.下载 MyBatis 源码和 MyBatis-Parent 源码 三.创建空项目.导入项目 四.编译 mybatis-parent 五.编译 mybatis 六.测试 总结 一 ...

  3. Mysql 中 not in 的查询优化

    本文为博主原创,转载请注明出处: 最近做性能优化时,通过开启 MySQL 的慢日志查询配置,发现 有一条慢sql,在这里记录下分析和优化的过程. 该慢 sql 如下: select id from f ...

  4. C:\Keil_v5\ARM\ARMCC\include\stdint.h contains an incorrect path.

    1.问题 在使用Keil uvison5打开例程代码进行学习时,发现部分.h文件无法读取 2.解决方法 1.找到如图的设置按钮(小锤子) 2.根据自己所用的是C/C++还是ARM选择(我这里是C/C+ ...

  5. [转帖]016 Linux 卧槽,看懂进程信息也不难嘛?top、ps

    016 Linux 卧槽,看懂进程信息也不难嘛?top.pshttps://my.oschina.net/u/3113381/blog/5455267 1 扒开看看 top 命令参数详情 Linux ...

  6. 最佳实践:基于vite3的monorepo前端工程搭建

    一.技术栈选择 1.代码库管理方式-Monorepo: 将多个项目存放在同一个代码库中 选择理由1:多个应用(可以按业务线产品粒度划分)在同一个repo管理,便于统一管理代码规范.共享工作流 选择理由 ...

  7. React中css的module

    处理css全局作用 现在有这样一个场景: A页面和B页面都有一个相同的类名 我们在A页面中有引入css. B页面没有css 在我们切换A和B页面的时候. A页面的css也作用在了B页面. 我们只希望A ...

  8. 你不知道的<input type="file">的小秘密

    限制file上传类型 很多时候,我们都需要使用 <input type="file"> 进行文件上传. 在上传的时候,我们需要对文件类型进行限制. 如果上传图片的时候. ...

  9. ClickHouse(08)ClickHouse表引擎概况

    目录 合并树家族 日志引擎系列 集成的表引擎 其他特殊的引擎 资料分享 参考文章 目前ClickHouse的表引擎主要有下面四个系列,合并树家族.日志引擎系列.集成的表引擎和其他特殊的引擎. 合并树家 ...

  10. docker的架构及工作原理(详解)

    目录 一.docker架构图 二.Client 客户端 三.Host 主机(docker引擎) 四.Image 镜像 五.Container 容器 六.镜像分层 可写的容器层 七.Volume 数据卷 ...