在 C++ 的 STL(标准模板库)中,排序操作主要通过 <algorithm> 头文件中的函数实现,其中最常用的是 std::sort 和 std::stable_sort。此外,还有针对特定场景的排序函数(如部分排序、堆排序等)。以下是详细介绍:
1. std::sort
功能
- 对容器或数组中的元素进行快速排序(通常实现为混合排序算法,如 introsort,结合了快速排序、堆排序和插入排序)。
- 时间复杂度:平均 O(N log N),最坏 O(N²)(但 STL 的实现通常通过递归深度限制避免最坏情况)。
- 不稳定排序:相等元素的相对顺序可能改变。
语法
#include <algorithm>
#include <vector>
// 对容器排序(默认升序)
std::sort(container.begin(), container.end());
// 对数组排序
int arr[] = {5, 2, 9, 1};
std::sort(arr, arr + 4); // 排序范围 [arr, arr + 4)
// 自定义比较函数(降序)
bool compare(int a, int b) {
return a > b; // 降序
}
std::sort(container.begin(), container.end(), compare);
// 使用 Lambda 表达式(C++11 起)
std::sort(container.begin(), container.end(), [](int a, int b) {
return a < b; // 升序
});
示例
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> nums = {3, 1, 4, 1, 5, 9, 2};
std::sort(nums.begin(), nums.end()); // 升序排序
for (int num : nums) {
std::cout << num << " "; // 输出: 1 1 2 3 4 5 9
}
// 降序排序
std::sort(nums.begin(), nums.end(), [](int a, int b) {
return a > b;
});
for (int num : nums) {
std::cout << num << " "; // 输出: 9 5 4 3 2 1 1
}
return 0;
}
2. std::stable_sort
功能
- 稳定排序:相等元素的相对顺序保持不变。
- 通常使用归并排序实现,时间复杂度:
- 最好情况:O(N log N)(当内存足够时)。
- 最坏情况:O(N (log N)²)(当内存不足时,使用多路归并)。
- 适用于需要保留相等元素原始顺序的场景(如按多关键字排序时先按次要关键字排序,再按主要关键字稳定排序)。
语法
std::stable_sort(container.begin(), container.end()); // 默认升序
std::stable_sort(container.begin(), container.end(), compare); // 自定义比较
示例
#include <iostream>
#include <vector>
#include <algorithm>
struct Person {
std::string name;
int age;
};
int main() {
std::vector<Person> people = {
{"Alice", 25},
{"Bob", 20},
{"Charlie", 25},
{"David", 20}
};
// 先按年龄升序,再按姓名升序(稳定排序保证年龄相同的顺序不变)
std::stable_sort(people.begin(), people.end(), [](const Person& a, const Person& b) {
return a.age < b.age;
});
for (const auto& p : people) {
std::cout << p.name << " (" << p.age << ")\n";
}
return 0;
}
3. 部分排序(Partial Sorting)
std::partial_sort
- 对部分元素排序(如前 K 个最小元素)。
- 时间复杂度:O(N log K)。
- 适用于只需要前 K 个元素的场景(如 Top K 问题)。
#include <algorithm>
#include <vector>
std::vector<int> nums = {5, 2, 9, 1, 3};
// 将前 3 个最小元素排序到前面
std::partial_sort(nums.begin(), nums.begin() + 3, nums.end());
// 结果可能是: 1 2 3 9 5(前 3 个有序,其余无序)
std::nth_element
- 快速选择算法,找到第 K 小的元素,并保证左边元素 ≤ 它,右边元素 ≥ 它。
- 时间复杂度:平均 O(N),最坏 O(N²)。
std::vector<int> nums = {5, 2, 9, 1, 3};
// 找到中位数(第 3 小的元素)
std::nth_element(nums.begin(), nums.begin() + 2, nums.end());
// nums[2] 是中位数(可能是 3)
4. 堆排序(Heap Sort)
std::make_heap + std::sort_heap
- 先将容器转换为堆结构,再排序。
- 时间复杂度:O(N log N)。
#include <algorithm>
#include <vector>
std::vector<int> nums = {5, 2, 9, 1, 3};
std::make_heap(nums.begin(), nums.end()); // 转换为最大堆
std::sort_heap(nums.begin(), nums.end()); // 堆排序(降序)
5. 自定义排序的注意事项
-
比较函数必须满足严格弱序:
- 若
a < b为true,则b < a必须为false。 - 若
a < b和b < c为true,则a < c必须为true。 - 违反会导致未定义行为(如
std::sort可能崩溃)。
- 若
-
避免对关联容器(如
std::set、std::map)手动排序:- 关联容器本身已排序,直接修改元素会破坏内部结构。
-
性能优化:
- 对小范围数据(如
< 16 元素),std::sort可能退化为插入排序。 - 对基本类型(如
int、double),编译器可能优化为更高效的实现。
- 对小范围数据(如
总结
| 排序函数 | 稳定性 | 时间复杂度 | 适用场景 |
|---|---|---|---|
std::sort | 不稳定 | O(N log N) | 通用快速排序 |
std::stable_sort | 稳定 | O(N log N) | 需要保留相等元素顺序 |
std::partial_sort | 不稳定 | O(N log K) | 前 K 个最小元素 |
std::nth_element | 不稳定 | O(N) | 快速选择第 K 小元素 |
std::make_heap + sort_heap | 不稳定 | O(N log N) | 堆排序(降序) |
根据需求选择合适的排序算法,可以显著提升程序效率!

470

被折叠的 条评论
为什么被折叠?



