C++ STL 標准庫中的 sort() 函數,本質就是一個模板函數。正如表 1 中描述的,該函數專門用來對容器或普通數組中指定范圍內的元素進行排序,排序規則默認以元素值的大小做升序排序,除此之外我們也可以選擇標准庫提供的其它排序規則(比如std::greater<T>
降序排序規則),甚至還可以自定義排序規則。
需要注意的是,sort() 函數受到底層實現方式的限制,它僅適用於普通數組和部分類型的容器。換句話說,只有普通數組和具備以下條件的容器,才能使用 sort() 函數:
- 容器支持的迭代器類型必須為隨機訪問迭代器。這意味着,sort() 只對 array、vector、deque 這 3 個容器提供支持。
- 如果對容器中指定區域的元素做默認升序排序,則元素類型必須支持
<
小於運算符;同樣,如果選用標准庫提供的其它排序規則,元素類型也必須支持該規則底層實現所用的比較運算符; - sort() 函數在實現排序時,需要交換容器中元素的存儲位置。這種情況下,如果容器中存儲的是自定義的類對象,則該類的內部必須提供移動構造函數和移動賦值運算符。
另外還需要注意的一點是,對於指定區域內值相等的元素,sort() 函數無法保證它們的相對位置不發生改變。例如,有如下一組數據:
2 1 2 3 2
可以看到,該組數據中包含多個值為 2 的元素,此時如果使用 sort() 函數進行排序,則值為 2 的這 3 個元素的相對位置可能會發生改變,比如排序結果為:
1 2 2 2 3
可以看到,原本紅色的元素 2 位於綠色 2 和橙色 2 的左側,但經過 sort() 函數排序之后,它們的相對位置發生了改變,即紅色 2 移動到了綠色 2 和橙色 2 的右側。
(實際場景中,如果需要保證值相等元素的相對位置不發生改變,可以選用 stable_sort() 排序函數)
1、頭文件
sort() 函數位於<algorithm>
頭文件中,因此在使用該函數前,程序中應包含如下語句:
#include <algorithm>
2.函數調用
sort() 函數有 2 種用法,其語法格式分別為:
//對 [first, last) 區域內的元素做默認的升序排序 void sort (RandomAccessIterator first, RandomAccessIterator last); //按照指定的 comp 排序規則,對 [first, last) 區域內的元素進行排序 void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
其中,first 和 last 都為隨機訪問迭代器,它們的組合 [first, last) 用來指定要排序的目標區域;另外在第 2 種格式中,comp 可以是 C++ STL 標准庫提供的排序規則(比如 std::greater<T>),也可以是自定義的排序規則。
關於如何自定義一個排序規則,除了《C++ STL關聯式容器自定義排序規則》一節介紹的 2 種方式外,還可以直接定義一個具有 2 個參數並返回 bool 類型值的函數作為排序規則。
3.例題
#include<iostream> #include<algorithm> using namespace std; main() { //sort函數第三個參數采用默認從小到大 int a[]={45,12,34,77,90,11,2,4,5,55}; sort(a,a+10); for(int i=0;i<10;i++) cout<<a[i]<<" "; }
#include<iostream> #include<algorithm> using namespace std; bool cmp(int a,int b); main(){ //sort函數第三個參數自己定義,實現從大到小 int a[]={45,12,34,77,90,11,2,4,5,55}; sort(a,a+10,cmp); for(int i=0;i<10;i++) cout<<a[i]<<" "; } //自定義函數 bool cmp(int a,int b){ return a>b; }
#include<iostream>
#include<algorithm>
#include"cstring"
using namespace std;
typedef struct student{
char name[20];
int math;
int english;
}Student;
bool cmp(Student a,Student b);
main(){
//先按math從小到大排序,math相等,按english從大到小排序
Student a[4]={{"apple",67,89},{"limei",90,56},{"apple",90,99}};
sort(a,a+3,cmp);
for(int i=0;i<3;i++)
cout<<a[i].name <<" "<<a[i].math <<" "<<a[i].english <<endl;
}
bool cmp(Student a,Student b){
if(a.math >b.math )
return a.math <b.math ;//按math從小到大排序
else if(a.math ==b.math )
return a.english>b.english ; //math相等,按endlish從大到小排序23
}
4.對於容器,容器中的數據類型可以多樣化
1) 元素自身包含了比較關系,如int,double等基礎類型,可以直接進行比較greater<int>() 遞減, less<int>() 遞增(省略)
關鍵代碼:
sort(arr.begin(),arr.end(),greater<int>());
2)元素本身為class或者struct,類內部需要重載< 運算符,實現元素的比較;
注意事項:bool operator<(const className & rhs) const; 如何參數為引用,需要加const,這樣臨時變量可以賦值;重載operator<為常成員函數,可以被常變量調用;
1 #include<iostream> 2 #include<algorithm> 3 #include"vector" 4 using namespace std; 5 typedef struct student{ 6 char name[20]; 7 int math; 8 //按math從大到小排序 9 inline bool operator < (const student &x) const { 10 return math>x.math ; 11 } 12 }Student; 13 main(){ 14 Student a[4]={{"apple",67},{"limei",90},{"apple",90}}; 15 sort(a,a+3); 16 for(int i=0;i<3;i++) 17 cout<<a[i].name <<" "<<a[i].math <<" " <<endl; 18 }
運行結果:
重載<也可以定義為如下格式:
1 struct Cmp{ 2 bool operator()(Info a1,Info a2) const { 3 return a1.val > a2.val; 4 } 5 };
轉載於:C++中sort函數使用方法 - 俊寶貝 - 博客園 (cnblogs.com)
C++ sort()排序函數用法詳解 (biancheng.net)