用std::greater()可直接实现降序排序,比先sort再reverse更高效;reverse仅翻转顺序,不排序;自定义lambda适用于结构体多字段排序;std::sort不稳定,需稳定时用std::stable_sort。

用 std::sort 配合 std::greater<int>()</int> 实现降序
默认的 std::sort 是升序,想倒序(即降序),最直接的方式是传入比较器 std::greater<int>()</int>。注意类型必须和 vector 元素类型一致,比如 vector<double></double> 就得用 std::greater<double>()</double>。
常见错误是漏写模板参数,写成 std::greater() —— 这在 C++17 后虽可能推导,但老标准或复杂类型下会编译失败。
示例:
#include <vector>
#include <algorithm>
#include <functional>
std::vector<int> v = {3, 1, 4, 1, 5};
std::sort(v.begin(), v.end(), std::greater<int>()); // → {5, 4, 3, 1, 1}
</int></int></functional></algorithm></vector>
用 std::reverse 前提是已升序,否则不是“倒序排序”
std::reverse 只是翻转容器顺序,和“排序”无关。它适合你已经调用过 std::sort 得到升序后,再翻转成降序;但若原 vector 是乱序,reverse 不会产生有序结果。
容易踩的坑:
- 误以为
std::reverse(v.begin(), v.end())能替代排序 —— 它不比较元素大小,只交换位置 - 在未排序的 vector 上用
reverse,得到的是原序列的镜像,不是降序排列
正确链式用法(不推荐,仅说明逻辑):
std::sort(v.begin(), v.end()); // 先升序 std::reverse(v.begin(), v.end()); // 再翻转 → 等效于降序
这比直接用 std::greater 多一次遍历,纯属冗余。
自定义比较函数更灵活,尤其对结构体或复杂逻辑
当 vector 存的是结构体、或需要按多个字段倒序(比如先按年龄降序,年龄相同时按姓名升序),就得写自定义 lambda 或函数对象。
关键点:
- lambda 返回
true表示第一个参数应排在第二个参数前面(即“a 在 b 前” ⇒ a 应该比 b “小” 或 “优先”) - 要倒序,就写
a > b;升序是a - 捕获列表为空时,lambda 可隐式转换为函数指针,兼容所有
std::sort版本
示例(结构体按 score 降序):
struct Student { int id; int score; };
std::vector<student> students = {{1, 85}, {2, 92}, {3, 78}};
std::sort(students.begin(), students.end(),
[](const Student& a, const Student& b) { return a.score > b.score; });
</student>
性能与稳定性:std::sort 是不稳定排序,std::stable_sort 可选但更慢
标准库 std::sort 通常实现为 introsort(快排+堆排+插排混合),平均 O(n log n),但不保证相等元素的相对位置 —— 即不稳定。如果你的倒序场景中,相同值的元素顺序很重要(比如分页后保持原始插入次序),就得换 std::stable_sort。
注意:
-
std::stable_sort时间复杂度仍是 O(n log n),但常数更大,内存开销也略高(可能需额外 O(n) 空间) - 它同样支持
std::greater和自定义比较器,用法完全一致 - 多数业务场景无需稳定,别盲目替换
例如:
std::stable_sort(v.begin(), v.end(), std::greater<int>()); </int>
真正要注意的,是别把“逆序”和“倒序排序”混淆:前者是物理翻转,后者是按值重新排列。选错方法会导致结果完全不符合预期,而且这种 bug 在测试数据少时还很难暴露。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











