编程基础:详解 C++ 中的 `std::sort` 函数

news2024/10/5 12:55:35

编程基础:详解 C++ 中的 std::sort 函数

在C++编程中,排序是非常常见的操作,而std::sort是C++标准库中用于排序的一个高效函数。它提供了灵活的排序功能,可以使用默认排序规则或自定义的比较函数。本文将深入探讨std::sort的用法、参数要求、性能特点以及如何结合实际场景灵活运用。

文章目录

  • 编程基础:详解 C++ 中的 `std::sort` 函数
    • 摘要
    • 一、什么是`std::sort`?
      • 1.1 定义
      • 1.2 应用场景
      • 1.3 基本语法
    • 二、`std::sort`的基本用法
      • 2.1 默认排序规则示例
      • 2.2 自定义排序规则示例
    • 三、`std::sort` 的高级用法
      • 3.1 对结构体排序
      • 3.2 对二维数组排序
    • 四、注意事项与常见错误
      • 4.1 使用`std::sort`时的注意事项
      • 4.2 常见错误
    • 五、总结

摘要

本文详细介绍了C++标准库中的std::sort函数。内容包括函数的定义、使用场景、参数要求、基本语法和常见示例。通过具体代码示例,展示了std::sort的基本用法和自定义排序的方式,并结合常见的错误和注意事项,帮助读者掌握如何使用这个强大的排序工具。

一、什么是std::sort

1.1 定义

std::sort是C++标准库中用于对元素进行排序的函数,位于<algorithm>头文件中。它采用了一种混合排序算法,通常是快速排序和插入排序的结合,能够在大多数情况下提供接近 O(n log n) 的时间复杂度。

核心原理

  • std::sort通常基于快速排序实现,但为了优化性能,可能会在较小数据量时切换到插入排序。
  • 默认情况下,std::sort按升序排序,但也支持自定义比较函数或仿函数。

1.2 应用场景

  • 当需要对容器(如数组、vector等)中的数据进行排序时,std::sort是高效且易用的工具。
  • 适用于需要按特定规则排序的数据结构,如排序成绩、按照字母顺序排列字符串等。

1.3 基本语法

std::sort(Iterator first, Iterator last);
std::sort(Iterator first, Iterator last, Compare comp);
  • firstlast:分别表示排序的范围 [first, last),即从 first 指向的元素开始,到 last 指向的元素前一个结束。
  • comp:可选的自定义比较函数,定义排序规则。默认按照小于运算符<进行排序。

二、std::sort的基本用法

2.1 默认排序规则示例

以下是一个使用std::sort对整数数组进行默认升序排序的简单示例:

#include <iostream>
#include <algorithm>  // 导入 std::sort
#include <vector>     // 导入 std::vector

int main() {
    std::vector<int> numbers = {5, 2, 9, 1, 5, 6};  // 初始化一个整型数组

    // 使用 std::sort 进行排序
    std::sort(numbers.begin(), numbers.end());

    // 输出排序后的结果
    std::cout << "Sorted numbers: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

解释

  • 该示例中,std::sort(numbers.begin(), numbers.end())按照升序对numbers中的整数排序。
  • begin()end() 分别返回容器的起始和结束迭代器,指定要排序的范围。

2.2 自定义排序规则示例

假设我们有一组数据,想要按降序排列。这时可以传递一个自定义比较函数或使用lambda表达式。

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    std::vector<int> numbers = {5, 2, 9, 1, 5, 6};  // 初始化一个整型数组

    // 使用 std::sort 并传入自定义的比较函数,按降序排序
    std::sort(numbers.begin(), numbers.end(), [](int a, int b) {
        return a > b;  // 定义降序排序规则:如果 a > b,表示 a 在 b 前
    });

    // 输出排序后的结果
    std::cout << "Sorted numbers in descending order: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

解释

  • 这里通过lambda表达式 [](int a, int b) { return a > b; },定义了一个自定义的降序排序规则。
  • std::sort的第三个参数是自定义的比较函数,它会根据该函数的返回值来确定元素的顺序。

三、std::sort 的高级用法

3.1 对结构体排序

除了简单的数据类型,std::sort还可以用于结构体等复杂数据类型的排序。比如我们有一个包含姓名和年龄的结构体,我们可以根据年龄对结构体进行排序。

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>

// 定义 Person 结构体
struct Person {
    std::string name;
    int age;
};

int main() {
    std::vector<Person> people = {
        {"Alice", 30},
        {"Bob", 25},
        {"Charlie", 35}
    };

    // 根据年龄对 people 进行排序
    std::sort(people.begin(), people.end(), [](const Person &a, const Person &b) {
        return a.age < b.age;  // 按年龄升序排序
    });

    // 输出排序结果
    std::cout << "Sorted people by age: " << std::endl;
    for (const auto &person : people) {
        std::cout << person.name << ": " << person.age << std::endl;
    }

    return 0;
}

解释

  • 在该示例中,我们定义了一个Person结构体,其中包含nameage字段。
  • 使用std::sortPerson对象进行排序时,通过自定义比较函数来指定排序规则(这里按照age升序排序)。

3.2 对二维数组排序

有时,我们可能需要对多维数组(如二维数组或嵌套的vector)进行排序。此时可以根据某一列的值进行排序。

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    std::vector<std::vector<int>> matrix = {
        {1, 2, 3},
        {3, 2, 1},
        {2, 3, 1}
    };

    // 按第二列的值进行排序
    std::sort(matrix.begin(), matrix.end(), [](const std::vector<int>& a, const std::vector<int>& b) {
        return a[1] < b[1];  // 按第二列升序排序
    });

    // 输出排序后的二维数组
    std::cout << "Sorted matrix by second column: " << std::endl;
    for (const auto& row : matrix) {
        for (int elem : row) {
            std::cout << elem << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}

解释

  • 在这个示例中,我们定义了一个二维数组matrix,并根据第二列的值对整个矩阵进行排序。

四、注意事项与常见错误

4.1 使用std::sort时的注意事项

  • 未定义行为:使用std::sort时,比较函数需要遵循严格弱序规则。即自定义比较函数需要确保满足!comp(b, a)comp(a, b)两者不可同时为真。
  • 大数据量排序:对于非常大的数据集,考虑使用std::stable_sort,它是稳定排序算法,能够保证相同元素的顺序不变。

4.2 常见错误

  • 错误使用比较函数:比较函数必须返回一个布尔值,表示两个元素的相对顺序。如果比较函数不符合这一规则,可能会导致未定义行为。

    错误示例:

    std::sort(vec.begin(), vec.end(), [](int a, int b) {
        return a - b;  // 错误!返回的是整数而非布尔值
    });
    

五、总结

std::sort是C++中功能强大的排序函数,能够在大多数场景下高效排序数据。它可以用于简单的升序或降序排序,也可以通过自定义比较函数实现复杂的排序逻辑。无论是处理简单的数据类型,还是自定义的复杂结构,std::sort都能够提供灵活的排序支持。

特性描述
默认排序使用<运算符,升序排序
自定义排序通过传入比较函数,自定义排序规则
稳定性std::sort不保证稳定性
复杂度最佳为 O(n log n),最差为 O(n^2)

✨ 我是专业牛,一个渴望成为大牛🏆的985硕士🎓,热衷于分享知识📚,帮助他人解决问题💡,为大家提供科研、竞赛等方面的建议和指导🎯。无论是科研项目🛠️、竞赛🏅,还是图像🖼️、通信📡、计算机💻领域的论文辅导📑,我都以诚信为本🛡️,质量为先!🤝

如果你觉得这篇文章对你有所帮助,别忘了点赞👍、收藏📌和关注🔔!你的支持是我继续分享知识的动力🚀!✨ 如果你有任何问题或需要帮助,随时留言📬或私信📲,我都会乐意解答!😊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2189889.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

YOLO11改进|卷积篇|引入全维动态卷积ODConv

目录 一、【ODConv】全维动态卷积1.1【ODConv】卷积介绍1.2【ODConv】核心代码 二、添加【ODConv】卷积2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、【ODConv】全维动态卷积 1.1【ODConv】卷积介绍 ODConv利用一种全新的多维注意力机…

12.1 Linux_进程间通信_管道

概述 什么是无名管道&#xff1a; 无名管道就是在内核中开辟了一块内存&#xff0c;进程1和进程2都可以访问这一块空间&#xff0c;从而实现通信。 当无名管道被创建时&#xff0c;父进程fd[0]指向管道的读端&#xff0c;fd[1]指向管道的写端。fork创建子进程后&#xff0c;…

4.人员管理模块(开始预备工作)——帝可得管理系统

目录 前言一、需求分析1.页面原型2.创建SQL 二、使用若依框架生成前后端代码1.添加目录菜单2.添加数据字典3.配置代码生成信息4.下载代码并导入项目5.快速导入方法 三、 总结 前言 提示&#xff1a;本篇讲解人员管理模块的开发的预备工作&#xff0c;包括需求分析、生成代码、…

点亮一个LED以及按键控制

目录 前言 LED 1.LED介绍 2.LED原理图 3.如何实现发光 按键 1.按键原理图 2.按键原理 按键控制LED 1.代码实现 2.软件消除抖动 软件消除抖动的原因 软件消抖如何实现 总结 前言 我们上节完成了开发环境的安装&#xff0c;本节我们就来实现我们的第一个程序吧(没安…

STM32的集成电路总线I2C

一、I2C简介 1.I2C总线特点 &#xff08;1&#xff09;两线制 I2C只需要SDA、SCL两根线来完成数据的传输和外围器件的扩展&#xff0c;器件地址采用软件寻址方式。 &#xff08;2&#xff09;多主机总线 I2C是一个真正的多主机总线&#xff0c;如果2个或多个主机同时初始化数据…

Day01-MySQL数据库介绍及部署

Day01-MySQL数据库介绍及部署 1、数据库服务概述介绍1.1 企业中为什么需要数据库&#xff1f;1.2 数据库服务作用1.3 数据库服务分类 2、数据库服务安装部署2.1 数据库版本应用2.2 数据库服务程序下载2.3 数据库软件安装方式2.3.1 二进制安装步骤 3、数据库服务初始化介绍3.1 安…

《15分钟轻松学 Python》教程目录

为什么要写这个教程呢&#xff0c;主要是因为即使是AI技术突起的时代&#xff0c;想要用好AI做开发&#xff0c;那肯定离不开Python&#xff0c;就算最轻量级的智能体都有代码块要写&#xff0c;所以不一定要掌握完完整整的Python&#xff0c;只要掌握基础就能应对大部分场景。…

react-问卷星项目(6)

实战 React常用UI组件库 Ant Design国内最常用组件库&#xff0c;稳定&#xff0c;强大Material UI国外流行TailWind UI 国外流行&#xff0c;收费 Ant Design 官网地址 这一章基本内容就是使用UI重构页面&#xff0c;也没有什么知识点&#xff0c;直接上代码 下载 npm ins…

git diff 查看到一行变动,但是目测无差异怎么办?

1. 目测无变化 直接用 git diff main.js 提示有一行变动&#xff0c;但是目测看不出来差异。 结果如图&#xff1a;up panel. 2. 大概是空格的问题&#xff0c;使用参数 --ws-error-highlightall $ git diff --ws-error-highlightall main.js结果如图: down panel.

【LeetCode: 19. 删除链表的倒数第 N 个结点 | 链表 + 快慢指针】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

大学生就业桥梁:基于Spring Boot的招聘系统

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…

【操作系统】引导(Boot)电脑的奇妙开机过程

&#x1f339;&#x1f60a;&#x1f339;博客主页&#xff1a;【Hello_shuoCSDN博客】 ✨操作系统详见 【操作系统专项】 ✨C语言知识详见&#xff1a;【C语言专项】 目录 什么是操作系统的引导&#xff1f; 操作系统的引导&#xff08;开机过程&#xff09; Windows操作系…

JavaScript-下篇

上篇我们学习了&#xff0c;一些基础语法和函数&#xff0c;现在我们学习下篇&#xff0c;主要包括,对象和事件。而对象又包括&#xff0c;数组Arrays&#xff0c;String字符串&#xff0c;BOM&#xff0c;DOM等 JS对象 Arrays数组 数组是一种特殊的对象&#xff0c;用于存储…

【多线程】多线程(8):单例模式:阻塞队列

【阻塞队列】 阻塞队列是在普通的“先进先出”队列的基础上&#xff0c;做出了扩充&#xff0c;可以组成「生产者消费者模型」 1.线程安全性 标准库是原有的队列Queue和其子类&#xff0c;默认都是“线程不安全的”&#xff0c;而阻塞队列是“线程安全的” 2.具有阻塞特性 …

【pytorch】张量求导3

再接上文,补一下作者未补完的矩阵运算的坑。 首先贴一下原作者的图,将其转化为如下代码: import torch import torch.nn as nn import torch.optim as optim# 定义一个简单的两层神经网络 class TwoLayerNet(nn.Module):def __init__(self):super(TwoLayerNet, self).__in…

Markdown 语法详解大全(超级版)(二)

Markdown 语法详解大全(超级版)&#xff08;二&#xff09; Markdown 语法详解大全(超级版)&#xff08;一&#xff09; Markdown 语法详解大全(超级版)&#xff08;二&#xff09; Markdown 语法详解大全(超级版)&#xff08;三&#xff09; &#xff08;歌词节选&#xff09…

Ubuntu 中 Redis ,MySQL 基本使用

1、Redis &#xff08;1&#xff09;启动Redis 服务端客户端命令 服务端 ps aux | grep redis 查看redis服务器进程 sudo kill -9 pid 杀死redis服务器 sudo redis-server /etc/redis/redis.conf 指定加载的配置文件客户端 连接redis&#xff1a; redis-cli运⾏测试命令&am…

C++结构体定义和创建

// // Created by 徐昌真 on 2024/10/5. // #include <iostream> using namespace std;int main() {//结构体的定义 struct 结构体名字 { 结构体成员名字 }struct Book{string name;double price;int value;}java; //java是创建的结构体//创建结构体//这是第一种方式Boo…

目标检测 DAB-DETR(2022)

文章目录 前言Query是什么&#xff0c;Detr收敛速度慢的原因是什么&#xff1f;改进策略位置先验和模型框架设置温度系数 前言 本文认为原始的Detr系列论文中&#xff1a;可学习的object queries仅仅是给model预测box提供了锚点&#xff08;中心点&#xff09;信息&#xff0c…

SpringBoot环境下古典舞交流平台的快速开发

第三章 系统分析 3.1 可行性分析 需要使用大部分精力开发的古典舞在线交流平台为了充分降低开发风险&#xff0c;特意在开发之前进行可行性分析这个验证系统开发是否可行的步骤。本文就会从技术角度&#xff0c;经济角度&#xff0c;还有操作角度等进行综合阐述。 3.1.1技术可行…