C++ sort()与stable_sort()使用指北(附示例代码)

 更新时间:2025年12月22日 10:35:18   作者:hellokandy  
这篇文章主要介绍了C++ sort()与stable_sort()使用的相关资料,std::sort()和std::stable_sort()都是C++标准库中的排序算法,文中通过代码将用法介绍的非常详细,需要的朋友可以参考下

在 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;
}

总结 

到此这篇关于C++ sort()与stable_sort()使用的文章就介绍到这了,更多相关C++ sort()与stable_sort()使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C和C++中的基本数据类型的大小及表示范围详解

    C和C++中的基本数据类型的大小及表示范围详解

    这篇文章主要介绍了C和C++中的基本数据类型的大小及表示范围详解,基本数据类型有int、long、long long、float、double、char、string,正文有详细介绍,欢迎参考
    2018-01-01
  • 一篇文章带你了解C语言二分查找

    一篇文章带你了解C语言二分查找

    这篇文章主要为大家详细介绍了C语言二分查找法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • COLORREF,COLOR,RGB,CString的转化总结分析

    COLORREF,COLOR,RGB,CString的转化总结分析

    实际的软件开发过程中,常需要用到非.net平台的代码。这时候就可能碰到ColorRef(也就是以int类型代表的颜色值或是以DWORD值表示的颜色)。这跟.net平台下的颜色的相互转换MS并没有直接实现
    2013-09-09
  • C++深浅拷贝和string类的两种写法详解

    C++深浅拷贝和string类的两种写法详解

    这篇文章主要为大家详细介绍了C++深浅拷贝和string类的两种写法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C++ 读文件 将文件内容读入到字符串string中的方法

    C++ 读文件 将文件内容读入到字符串string中的方法

    今天小编就为大家分享一篇C++ 读文件 将文件内容读入到字符串string中的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • VS2022连接sqlserver数据库教程

    VS2022连接sqlserver数据库教程

    本文主要介绍了VS2022连接sqlserver数据库教程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Qt6实现调用摄像头并显示画面

    Qt6实现调用摄像头并显示画面

    这篇文章主要为大家详细介绍了Qt6如何实现调用摄像头并显示画面的效果,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以参考一下
    2023-02-02
  • C++实现一行一行读取文本的方法

    C++实现一行一行读取文本的方法

    今天小编就为大家分享一篇C++实现一行一行读取文本的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • 详解C语言中的fopen()函数和fdopen()函数

    详解C语言中的fopen()函数和fdopen()函数

    这篇文章主要介绍了详解C语言中的fopen()函数和fdopen()函数,注意其之间指针功能相关的区别,需要的朋友可以参考下
    2015-08-08
  • C语言实现随机抽奖程序

    C语言实现随机抽奖程序

    这篇文章主要为大家详细介绍了C语言实现随机抽奖程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09

最新评论