在c++++中,stl的sort()和priority_queue支持自定义排序规则。1. sort()函数通过传入比较函数或lambda表达式实现自定义排序,如按成绩从高到低排序学生结构体;2. priority_queue需提供比较器作为模板参数,如实现最小堆处理任务优先级;3. 仿函数适合复用和复杂逻辑,lambda则用于一次性简洁操作。掌握这些方法可灵活应对不同排序需求。

在C++中,STL(标准模板库)为我们提供了非常方便的排序工具,比如
sort()和优先队列
priority_queue。但默认情况下它们都是按升序或降序排列基本类型,当我们面对自定义类型或者需要更复杂的排序规则时,就需要自己动手写比较逻辑了。

下面我们就来看看如何灵活使用这些工具实现自定义排序。

1. sort()
函数中的自定义比较函数
std::sort()是STL中最常用的排序函数,默认对基本类型进行升序排列。如果我们想对结构体、类对象或者改变排序方式,就需要传入一个比较函数或lambda表达式。
举个例子:

我们有一个学生结构体,想要按照成绩从高到低排序:
struct Student {
string name;
int score;
};
bool compareByScore(const Student& a, const Student& b) {
return a.score > b.score; // 成绩高的排前面
}
vector students = {{"Alice", 88}, {"Bob", 95}, {"Charlie", 70}};
sort(students.begin(), students.end(), compareByScore); 你也可以用lambda表达式简化代码:
sort(students.begin(), students.end(), [](const Student& a, const Student& b) {
return a.score > b.score;
});注意点:
- 比较函数必须返回布尔值。
- 如果希望稳定排序,可以用
stable_sort()
。 - 排序前确保容器支持随机访问迭代器(如
vector
、deque
),否则会出错。
2. 在priority_queue
中使用自定义比较器
priority_queue默认是一个最大堆,底层使用
vector,并依赖于比较函数来决定元素优先级。要自定义排序规则,需要提供一个比较器作为模板参数。
举个场景:
我们要实现一个最小堆来保存任务,任务优先级越小越先执行:
struct Task {
int priority;
string description;
};
// 自定义比较器
struct CompareTask {
bool operator()(const Task& a, const Task& b) {
return a.priority > b.priority; // 小优先
}
};
priority_queue, CompareTask> taskQueue;
taskQueue.push({3, "Write code"});
taskQueue.push({1, "Fix bug"});
taskQueue.push({2, "Test feature"}); 此时,
Fix bug这个任务会被优先取出。
关键点:
- 比较器要用结构体或类封装,并重载
operator()
- 注意比较逻辑是否符合你的“优先”定义(例如是小优先还是大优先)
- 可以配合lambda吗?不可以直接用于模板参数,但可以用
function
包装后搭配std::priority_queue
的替代实现(比如手写)
3. 使用仿函数与Lambda表达式的区别
在实际开发中,很多人会纠结该用仿函数(functor)还是lambda表达式。
仿函数的优点:
- 可复用:可以多次调用
- 更适合复杂逻辑
- 可以有状态(虽然一般不推荐)
Lambda的优点:
- 简洁:适合一次性使用
- 可以内联写在调用处,提高可读性
比如上面的sort排序,如果只用一次,用lambda就足够;但如果多个地方都需要同样的排序规则,建议封装成仿函数。
基本上就这些。掌握好这些方法之后,就能根据具体需求灵活地使用STL中的排序功能了。








