C++ 排序指南

在 C++ 中,std::sort 是一個非常強大且常用的函數,用于對容器或數組中的元素進行排序。它定義在 <algorithm> 頭文件中。

std::sort 的基本語法

std::sort 的基本語法有以下幾種形式:

  1. 默認升序排序:

    std::sort(first, last);
    
    • first: 指向要排序范圍的起始元素的迭代器(包含)。
    • last: 指向要排序范圍的結束元素之后一個位置的迭代器(不包含)。
    • 這種形式會使用元素的默認 < 運算符進行比較,實現升序排序。
  2. 自定義比較規則排序:

    std::sort(first, last, comp);
    
    • first, last: 同上。
    • comp: 一個可調用對象(函數指針、函數對象或 Lambda 表達式),用于定義比較規則。它接受兩個參數,并返回一個 bool 值。如果第一個參數“小于”第二個參數(即應該排在第二個參數之前),則返回 true

std::sort 的特點

  • 頭文件: 必須包含 <algorithm>
  • 迭代器類型: 需要隨機訪問迭代器(RandomAccessIterator)。std::vectorstd::dequestd::string 和 C 風格數組都提供隨機訪問迭代器,因此它們可以直接使用 std::sortstd::liststd::forward_list 不提供隨機訪問迭代器,它們有自己的 sort() 成員函數。
  • 排序算法: std::sort 通常使用 IntroSort(內省式排序),這是一種混合排序算法,結合了快速排序、堆排序和插入排序的優點,以確保在各種情況下的平均和最壞時間復雜度都為 O(N log N)。
  • 原地排序: std::sort 是原地排序算法,它直接修改原始容器中的元素,不創建副本。

使用示例

1. 對 std::vector<int> 進行升序排序
#include <iostream>
#include <vector>
#include <algorithm> // 包含 std::sortint main() {std::vector<int> numbers = {5, 2, 8, 1, 9, 4};// 對向量進行升序排序std::sort(numbers.begin(), numbers.end());std::cout << "升序排序后的數字: ";for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl; // 輸出: 1 2 4 5 8 9return 0;
}
2. 對 std::vector<int> 進行降序排序

方法一:使用 std::greater<T> 函數對象

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional> // 包含 std::greaterint main() {std::vector<int> numbers = {5, 2, 8, 1, 9, 4};// 對向量進行降序排序std::sort(numbers.begin(), numbers.end(), std::greater<int>());std::cout << "降序排序后的數字: ";for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl; // 輸出: 9 8 5 4 2 1return 0;
}

方法二:使用 Lambda 表達式

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> numbers = {5, 2, 8, 1, 9, 4};// 使用 Lambda 表達式進行降序排序std::sort(numbers.begin(), numbers.end(), [](int a, int b) {return a > b; // 如果 a 大于 b,則 a 排在 b 之前});std::cout << "降序排序后的數字 (Lambda): ";for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl; // 輸出: 9 8 5 4 2 1return 0;
}
3. 對 std::string 中的字符進行排序
#include <iostream>
#include <string>
#include <algorithm>int main() {std::string s = "programming";// 對字符串中的字符進行升序排序std::sort(s.begin(), s.end());std::cout << "排序后的字符串: " << s << std::endl; // 輸出: aggimnoprrreturn 0;
}
4. 對自定義結構體或類進行排序 (按特定成員)

假設有一個 Student 結構體,我們想按分數對其進行排序。

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>struct Student {std::string name;int score;
};// 自定義比較函數(可作為 Lambda 表達式或獨立函數)
bool compareStudents(const Student& s1, const Student& s2) {return s1.score < s2.score; // 按分數升序排序
}int main() {std::vector<Student> students = {{"Alice", 85},{"Bob", 92},{"Charlie", 78},{"David", 92} // Bob 和 David 分數相同};// 使用自定義比較函數對學生進行排序std::sort(students.begin(), students.end(), compareStudents);std::cout << "按分數排序后的學生: " << std::endl;for (const Student& s : students) {std::cout << s.name << ": " << s.score << std::endl;}/* 輸出:Charlie: 78Alice: 85Bob: 92David: 92*/// 假設分數相同,按名字字母順序排序std::sort(students.begin(), students.end(), [](const Student& s1, const Student& s2) {if (s1.score != s2.score) {return s1.score < s2.score; // 分數不同時按分數排序}return s1.name < s2.name; // 分數相同時按名字排序});std::cout << "\n按分數然后按名字排序后的學生: " << std::endl;for (const Student& s : students) {std::cout << s.name << ": " << s.score << std::endl;}/* 輸出:Charlie: 78Alice: 85Bob: 92David: 92 (注意:這里Bob和David的相對順序可能不變,因為它們在原始數據中是Bob在前。如果想確保 David 在 Bob 之后,比較器應返回 true 只有當 s1 嚴格小于 s2。當前輸出是正確的,因為 Bob 92, David 92, Bob 的 'B' < David 的 'D'。實際輸出取決于 `std::sort` 的穩定性,但 `std::sort` 通常是不穩定的,對于相等元素,相對順序可能改變。如果需要穩定性,使用 `std::stable_sort`。但在這個例子中,因為Bob和David名字不同,所以會進一步排序。*/return 0;
}

總結

std::sort 是 C++ 中進行排序的首選工具,因為它高效、靈活,并且易于使用。通過提供自定義比較規則,你可以根據幾乎任何條件對各種數據類型進行排序。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/93259.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/93259.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/93259.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RS232串行線是什么?

RS232串行線是什么&#xff1f;RS232串行線是一種用于串行通信的標準化接口&#xff0c;廣泛應用于早期計算機、工業設備、儀器儀表等領域的短距離數據傳輸。以下是其核心要點解析&#xff1a;1. 基本定義 全稱&#xff1a;RS232&#xff08;Recommended Standard 232&#xff…

k8s-scheduler 解析

學習文檔 官網的k8s上關于scheduler的文檔基本可以分為這兩部分 介紹 scheduler 的基本概念 介紹 scheduler 的配置 KubeSchedulerConfiguration 的參數 介紹 scheduler 的命令行參數 調度框架解析 Scheduling-framework 解析 kube-scheduler 選擇 node 通過下面這兩步…

前端簡歷1v1修改: 優化項目經驗

今天有人找我優化前端簡歷&#xff0c;分享一下如何優化項目經驗描述。這是修改前的版本&#xff1a;項目為Web前端開發&#xff0c;但描述為APP應用&#xff0c;包含某某功能。起初我感到困惑&#xff0c;因為前端技術棧使用Vue&#xff0c;為何項目類型是APP&#xff1f;后來…

K8S企業級應用與DaemonSet實戰解析

目錄 一、概述 二、YAML文件詳解 三、企業應用案例 3.1 環境準備 3.2 擴縮容 3.3 滾動更新 3.4 回滾 四、自定義更新策略 4.1類型 4.2 設置方式 4.3 配置案例 一、 DaemonSet 概述 DaemonSet 工作原理 Daemonset 典型的應用場景 DaemonSet 與 Deployment 的區別…

Celery在Django中的應用

Celery在Django中的應用一、項目配置二、異步任務2.1 普通用法2.1.1 通過delay2.1.2 通過apply_async2.2 高級用法2.2.1 任務回調&#xff08;Callback&#xff09;2.2.2 任務鏈&#xff08;Chaining&#xff09;2.2.3 任務組&#xff08;Group&#xff09;2.2.4 任務和弦&…

DeepSeek生成的高精度大數計算器

# 高精度計算器&#xff08;精確顯示版&#xff09;1. **精確顯示優化**&#xff1a;- 新增print_mpfr()函數專門處理MPFR數值的打印- 自動移除多余的尾隨零和小數點- 確保所有浮點結果都以完整十進制形式顯示&#xff0c;不使用科學計數法2. **浮點精度修復**&#xff1a;- 所…

08--深入解析C++ list:高效操作與實現原理

1. list介紹1.1. list概述template < class T, class Alloc allocator<T> > class list;Lists are sequence containers that allow constant time insert and erase operations anywhere within the sequence, and iteration in both directions.概述&#xff1…

GraphQL從入門到精通完整指南

目錄 什么是GraphQLGraphQL核心概念GraphQL Schema定義語言查詢(Queries)變更(Mutations)訂閱(Subscriptions)Schema設計最佳實踐服務端實現客戶端使用高級特性性能優化實戰項目 什么是GraphQL GraphQL是由Facebook開發的一種API查詢語言和運行時。它為API提供了完整且易于理…

使用 Dockerfile 與 Docker Compose 結合+Docker-compose.yml 文件詳解

使用 Dockerfile 與 Docker Compose 結合的完整流程 Dockerfile 用于定義單個容器的構建過程&#xff0c;而 Docker Compose 則用于編排多個容器。以下是結合使用兩者的完整方法&#xff1a; 1. 創建 Dockerfile 在項目目錄中創建 Dockerfile 定義應用鏡像的構建過程&#xff1…

15 ABP Framework 開發工具

ABP Framework 開發工具 概述 該頁面詳細介紹了 ABP Framework 提供的開發工具和命令行界面&#xff08;CLI&#xff09;&#xff0c;用于創建、管理和定制 ABP 項目。ABP CLI 是主要開發工具&#xff0c;支持項目腳手架、模塊添加、數據庫遷移管理及常見開發任務自動化。 ABP …

力扣top100(day02-01)--鏈表01

160. 相交鏈表 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) {* val x;* next null;* }* }*/ public class Solution {/*** 查找兩個鏈表的相交節點* param headA 第一個…

LLM 中 語音編碼與文本embeding的本質區別

直接使用語音編碼,是什么形式,和文本的區別 直接使用語音編碼的形式 語音編碼是將模擬語音信號轉換為數字信號的技術,其核心是對語音的聲學特征進行數字化表征,直接承載語音的物理聲學信息。其形式可分為以下幾類: 1. 基于波形的編碼(保留原始波形特征) 脈沖編碼調制…

模型選擇與調優

一、模型選擇與調優在機器學習中&#xff0c;模型的選擇和調優是一個重要的步驟&#xff0c;它直接影響到最終模型的性能1、交叉驗證在任何有監督機器學習項目的模型構建階段&#xff0c;我們訓練模型的目的是從標記的示例中學習所有權重和偏差的最佳值如果我們使用相同的標記示…

vue+Django農產品推薦與價格預測系統、雙推薦+機器學習預測+知識圖譜

vueflask農產品推薦與價格預測系統、雙推薦機器學習價格預測知識圖譜文章結尾部分有CSDN官方提供的學長 聯系方式名片 文章結尾部分有CSDN官方提供的學長 聯系方式名片 關注B站&#xff0c;有好處&#xff01;編號: D010 技術架構: vueflaskmysqlneo4j 核心技術&#xff1a; 基…

數據分析小白訓練營:基于python編程語言的Numpy庫介紹(第三方庫)(下篇)

銜接上篇文章&#xff1a;數據分析小白訓練營&#xff1a;基于python編程語言的Numpy庫介紹&#xff08;第三方庫&#xff09;&#xff08;上篇&#xff09;&#xff08;十一&#xff09;數組的組合核心功能&#xff1a;一、生成基數組np.arange().reshape() 基礎運算功能&…

負載因子(Load Factor) :哈希表(Hash Table)中的一個關鍵性能指標

負載因子&#xff08;Load Factor&#xff09; 是哈希表&#xff08;Hash Table&#xff09;中的一個關鍵性能指標&#xff0c;用于衡量哈希表的空間利用率和發生哈希沖突的可能性。一&#xff1a;定義負載因子&#xff08;通常用希臘字母 λ 表示&#xff09;的計算公式為&…

監控插件SkyWalking(一)原理

一、介紹 1、簡介 SkyWalking 是一個 開源的 APM&#xff08;Application Performance Monitoring&#xff0c;應用性能監控&#xff09;和分布式追蹤系統&#xff0c;主要用于監控、追蹤、分析分布式系統中的調用鏈路、性能指標和日志。 它由 Apache 基金會托管&#xff0c;…

【接口自動化測試】---自動化框架pytest

目錄 1、用例運行規則 2、pytest命令參數 3、pytest配置文件 4、前后置 5、斷言 6、參數化---對函數的參數&#xff08;重要&#xff09; 7、fixture 7.1、基本用法 7.2、fixture嵌套&#xff1a; 7.3、請求多個fixture&#xff1a; 7.4、yield fixture 7.5、帶參數…

Flink Stream API 源碼走讀 - socketTextStream

概述 本文深入分析了 Flink 中 socketTextStream() 方法的源碼實現&#xff0c;從用戶API調用到最終返回 DataStream 的完整流程。 核心知識點 1. socketTextStream 方法重載鏈 // 用戶調用入口 env.socketTextStream("hostname", 9999)↓ 補充分隔符參數 env.socket…

待辦事項小程序開發

1. 項目規劃功能需求&#xff1a;添加待辦事項標記完成/未完成刪除待辦事項分類或標簽管理&#xff08;可選&#xff09;數據持久化&#xff08;本地存儲&#xff09;2. 實現功能添加待辦事項&#xff1a;監聽輸入框和按鈕事件&#xff0c;將輸入內容添加到列表。 標記完成/未完…