STL库里的排序函数

在 C++ 的 STL(标准模板库)中,排序操作主要通过 <algorithm> 头文件中的函数实现,其中最常用的是 std::sortstd::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. 自定义排序的注意事项

  1. 比较函数必须满足严格弱序

    • a < btrue,则 b < a 必须为 false
    • a < bb < ctrue,则 a < c 必须为 true
    • 违反会导致未定义行为(如 std::sort 可能崩溃)。
  2. 避免对关联容器(如 std::setstd::map)手动排序

    • 关联容器本身已排序,直接修改元素会破坏内部结构。
  3. 性能优化

    • 对小范围数据(如 < 16 元素),std::sort 可能退化为插入排序。
    • 对基本类型(如 intdouble),编译器可能优化为更高效的实现。

总结

排序函数稳定性时间复杂度适用场景
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)堆排序(降序)

根据需求选择合适的排序算法,可以显著提升程序效率!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code .

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值