C++ —— sort与比较器
一、基础知识
c++内置一个排序函数:sort,其头文件为#include<algorithm>,函数原型为:
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
需要三个参数:
- 起始位置(迭代器),参与排序的第一个元素的地址
- 结束位置(迭代器),参与排序的最后一个元素的后一个元素的地址
- 比较器(函数指针),此参数可以省略,省略后自动使用“less<>”结构体按升序排序,而该结构体只依赖于“ operator< ”,即<号 。因此,参与排序的元素必须具有 “ < ”,要么是int,double等自带的<,要么是程序员自己重载的<
可省略比较器的示例:
以下仅演示重载 < 的情况,自带 < 过于简单不必赘述。
using namespace std;
struct node {
int x;
bool operator< (node& a) const{ //为node类型重载的<
return x < a.x ? true : false;
}
};
void test01() {
vector<node>v;
node a, b, c, d;
a.x = 3;
b.x = 4;
c.x = 1;
d.x = 2;
v.push_back(a); v.push_back(b); v.push_back(c); v.push_back(d);
sort(v.begin(), v.end()); //由于node类型现在具有<,可以省略比较器
for (int i = 0; i < v.size(); ++i)
cout << v[i].x << endl;
}
int main() {
test01();
}
结果如下:
二、比较器
如果我们不想给指定类型重载<,但又想使用sort为这种类型排序。或者是我们想按非默认的方式进行排序,例如降序。此时我们就可以带上比较器。比较器本质上是一个函数指针,其对应的函数可以满足排序需求。因此我们要写的是一个函数,也可以是一个结构体伪函数。
自定义函数:
//自定义函数,降序
bool mycmp(const node& a,const node& b) {
return a.x > b.x ? true : false;
}
sort改为:
sort(v.begin(), v.end(), mycmp);
mycmp是指向mycmp()函数的指针,直接作为比较器。
结构体伪函数:
//伪函数,降序
struct mycmp2
{
bool operator() (const node& a, const node& b) {
return a.x > b.x ? true : false;
}
};
sort改为:
sort(v.begin(), v.end(), mycmp2());
mycmp2是结构体,mycmp2()作为比较器。
结果如下:
比较器函数的写法:
- 一般定义在类或结构体外部(理论上写在内部的也可以通过函数指针取到地址并作为比较器,但暂且没找到正确写法)
- 返回类型必须是bool
- 传入参数必须为2个。我们只希望sort对元素进行排序,排序过程中不能对值产生影响,所以一般用const修饰传入参数。同时,为加快速度,一般传引用
- 如何按需求编写比较器?记住如下规则:当返回true时,排序后第一个传参会排在前面,第二个传参排在后面;返回false时,排序后第二个传参排在前面,第一个排在后面。也可以这样理解:对于一个容器,从前往后取数,每次取相邻两个,传给比较器进行比较,每次结果都是true,则该容器是正确排序的容器。
例如:我们希望按x的降序对node型元素排序,也就是说需求如下:a.x < b.x 时将b排在a前面,而a.x > b.x时,将a排在b前面,对于=的情况没有要求,根据规则编写如下:
bool mycmp(const node& a,const node& b) {
return a.x > b.x ? true : false;
}
a.x > b.x时返回true,则排序后第一个传参a排在前面,第二个传参b排在后面;
a.x<=b.x时返回false,则排序后第二个传参b排在前面,第一个传参a排在后面,满足需求
避坑:
优先队列priority_queue底层是堆,比较器比较的对象是从叶子到根的元素,因此最后自动排序出来的顺序是反直觉的。例如
priority_queue <int,vector<int>,less<int> >q;
该优先队列是大根堆,按降序排列
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现