C++ sort() 与 stable_sort() 使用指北

部署运行你感兴趣的模型镜像

在 C++ 标准库中,std::sort() 和 std::stable_sort() 都用于对容器中的元素进行排序,但二者最根本的区别在于稳定性。

1、排序的稳定性是个什么玩意

如果两个元素相等(比较结果为等价),排序后它们的相对顺序与原序列中保持一致。

2、到底谁更稳定

std::sort() 是不稳定的排序算法,意味着相等元素的相对顺序在排序后可能被改变。
std::stable_sort() 是稳定排序,保证相等元素的原始输入顺序在排序后保持不变。

3、它们内部的实现方式

std::sort() 通常采用Introsort(内省排序),结合快速排序、堆排序和插入排序,平均性能极佳。
std::stable_sort() 多基于归并排序(Merge Sort),因其天然具备稳定性,适合分治策略下的有序合并。
尽管 stable_sort() 提供了稳定性保障,但其代价是更高的内存消耗和潜在的性能下降(尤其在大数据集上)。对于金融系统、考试排名、事件日志等场景,稳定性是硬性需求,应无条件选用 stable_sort()。

4、小结

  • std::sort:更快、更省内存,但不保证稳定性。
  • std::stable_sort:稍慢、更耗内存,但保证稳定性。
  • 一句话:性能优先用 sort,顺序敏感用 stable_sort。
  • 备注:对于频繁排序的小型容器,可考虑使用 std::list::sort()

5、示例代码

#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <algorithm>//sort

using std::vector;
using std::list;
using std::string;

struct Student
{
    string name;
    double score;
    Student(const string &n, double s) : name(n), score(s) {}
    // 重载 operator< 以按score升序排序(list::sort)
    bool operator<(const Student& other) const {
        return score < other.score;
    }
};

bool CompareByScore(const Student& a, const Student& b) {
    return a.score > b.score; // 降序
}
//
bool CompareStudent(const Student& a, const Student& b) {
    if (a.score != b.score){
        return a.score < b.score;
    }
    return a.name < b.name; // 成绩相同时按名字升序
}

int main(int argc, char *argv[])
{
    std::vector<Student> studentArray = {
        {"Candy", 91.0},
        {"Body", 91.0},
        {"Andy", 91.0},
        {"Lucy", 91.0},
        {"Lily", 90.5},
        {"Luck", 92.5},
        {"Kandy", 95.0},
    };

    do{
        std::cout << "v1: std::sort" << std::endl;
        auto v1 = studentArray;
        std::sort(v1.begin(), v1.end(), [](const Student &a, const Student &b){
            return a.score > b.score;//降序
        });
        for (const auto& s : v1) {
            std::cout << s.name << ": " << s.score << "\n";
        }
    }while(false);


    do{
        // 使用 stable_sort 保证同分学生顺序不变
        std::cout << "\nv2: std::stable_sort" << std::endl;
        auto v2 = studentArray;
        std::stable_sort(v2.begin(), v2.end(), CompareByScore);
        for (const auto& s : v2) {
            std::cout << s.name << ": " << s.score << "\n";
        }
    }while(false);


    do{
        // 对于频繁排序的小型容器,可考虑使用 std::list::sort()(稳定且链表友好)
        std::list<Student> studentList;
        for (const auto& s : studentArray){
            studentList.push_back(s);
        }

        // 使用 std::list::sort() 进行排序
        std::cout << "\nlist1: sort" << std::endl;
        auto list1 = studentList;
        list1.sort();                 // 使用 operator<
        for (const auto& s : list1) {
            std::cout << s.name << ": " << s.score << "\n";
        }

        //使用自定义比较函数
        std::cout << "\nlist2: CompareStudent" << std::endl;
        auto list2 = studentList;
        list2.sort(CompareStudent);
        for (const auto& s : list2) {
            std::cout << s.name << ": " << s.score << "\n";
        }
    }while(false);

    return 0;
}

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hellokandy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值