std::sort必须传入起始和末尾迭代器(末尾为“末尾之后”位置),不接受数组长度或容器对象;vector用begin()/end(),C数组用指针算术如arr+5;传反顺序或错误类型将导致编译失败、段错误或未定义行为;自定义比较推荐按值捕获的lambda。

std::sort 用法和必须传迭代器
直接用 std::sort 对数组或容器排序,核心是传两个迭代器:起始和末尾(注意是「末尾之后」的位置)。它不接受裸指针数组长度、也不接受容器对象本身——传错类型或范围,编译失败或行为未定义。
- 对
std::vector:用v.begin()和v.end(),别写成v.size()或&v[0]+ 数字偏移 - 对 C 风格数组:必须用指针算术,比如
int arr[5]; std::sort(arr, arr + 5);,写成arr, arr + sizeof(arr)是常见错误 - 传反了顺序(如
end, begin)会导致段错误或静默崩溃,调试时难定位
自定义比较函数:lambda 最常用,但注意捕获和生命周期
升序降序、结构体字段排序、多条件优先级,全靠比较函数。lambda 写起来快,但容易在异步或长生命周期场景下捕获悬空引用。
- 安全写法:按值捕获局部变量(
[val]() { return ...; }),或确保引用对象生命周期覆盖整个排序过程 - 结构体排序别直接写
return a.x 就完事——如果 <code>x是double或指针,要考虑NaN或空指针导致的未定义行为 - 用函数对象(functor)比全局函数更易复用,但模板实例化可能增大二进制体积,小项目无所谓,嵌入式需留意
std::sort 不稳定,要稳定得换 std::stable_sort
当相等元素的原始相对位置必须保留(比如先按分数排、再按提交时间排),std::sort 不保证这点。它底层是 introsort(快排+堆排+插排混合),平均 O(n log n),但不稳定。
-
std::stable_sort时间复杂度最坏 O(n log²n),内存占用略高(可能需要额外 O(n) 缓存),但稳定性有保障 - 对小数据量(std::sort 内部会自动切到插入排序;
std::stable_sort也类似,但阈值不同,不用手动优化 - 别指望用
std::sort加“加权索引”模拟稳定——逻辑复杂且易出错,直接换函数更可靠
字符串数组排序要注意 char* 和 std::string 的区别
排序 char* 数组时,std::sort 默认比的是指针值,不是字符串内容;而 std::vector<:string></:string> 默认按字典序比较,这是很多人踩坑的源头。
立即学习“C++免费学习笔记(深入)”;
-
const char* arr[] = {"zebra", "apple"};→ 必须传自定义比较:[](const char* a, const char* b) { return std::strcmp(a, b) -
std::vector<:string></:string>可直接用std::sort(v.begin(), v.end()),但注意std::string比较默认区分大小写,要忽略大小写得自己写逻辑 - UTF-8 字符串不能靠
strcmp或std::string::operator<正确排序,那是 locale 和 collation 层的事,C++20 前基本没标准解
排序的边界往往不在算法本身,而在你传进去的那两个迭代器是否真指向合法连续内存、比较函数是否满足严格弱序、以及你有没有意识到「稳定」不是默认选项。这些地方一松懈,程序可能跑几天才暴露问题。










