參考:
https://baike.baidu.com/item/sort%E5%87%BD%E6%95%B0/11042699?fr=aladdin
https://blog.csdn.net/ljl1015ljl/article/details/88096118
https://www.cnblogs.com/TX980502/p/8528840.html
sort函數用於C++中,對給定區間所有元素進行排序,默認為升序,也可進行降序排序。sort函數進行排序的時間復雜度為n*log2n,比冒泡之類的排序算法效率要高,sort函數包含在頭文件為#include<algorithm>的c++標准庫中。
函數原型
參數
功能
關於cmp子函數返回值的規則說明
若滿足某個條件時,a1應該在a2前面,則返回true,否則返回false。
說簡單點就是:返回true說明參數一應該排在參數二前面,否則想發。具體參見下面的實例。
sort類函數
整個sort類函數有很多其他東西可以使用,但是參數意義類似,下面只演示sort。
函數名 | 功能描述 |
---|---|
sort | 對給定區間所有元素進行排序 |
stable_sort | 對給定區間所有元素進行穩定排序 |
partial_sort | 對給定區間所有元素部分排序 |
partial_sort_copy | 對給定區間復制並排序 |
nth_element | 找出給定區間的某個位置對應的元素 |
is_sorted | 判斷一個區間是否已經排好序 |
partition | 使得符合某個條件的元素放在前面 |
stable_partition |
相對穩定的使得符合某個條件的元素放在前面
|
sort和stable_sort函數都應該掌握。stable_sort函數可以參見下文第五種用法中的例子。
用sort進行排序(用法一)
對基本類型的數組從小到大排序: sort(數組名+n1,數組名+n2);
其中,n1和n2都是int類型的表達式,可以包含變量。若n1=0,則 + n1可以不寫。
功能是:將下標范圍[n1,n2)的元素從小到大排序。注意:下標n2的元素是不參與排序的。
例如:
int a[] = {15,4,3,9,7,2,6}; sort(a,a+7); //對整個數組從小到大排序 int a[] = {15,4,3,9,7,2,6}; sort(a,a+3); // 結果: {3,4,15,9,7,2,6} int a[] = {15,4,3,9,7,2,6}; sort(a+2,a+5); //結果: {15,4,3,7,9,2,6}
用sort進行排序(用法二)
對元素類型為T的基本類型數組從大到小排序: sort(數組名+n1,數組名+n2,greater<T>( )) ;
同理,上述代碼是對下標區間[n1,n2)的元素作從大到小排序。下標n2的元素不參與排序。
例如:
int a[] = {15,4,3,9,7,2,6}; sort(a+1,a+4,greater<int>( )); // 結果: {15,9,4,3,7,2,6}
用sort進行排序(用法三)
用自定義的排序規則,對任何類型T的數組排序。
sort(數組名+n1,數組名+n2,排序規則結構名( ));
排序規則結構體的定義方式:
1 struct 結構名 2 { 3 bool operator()( const T & a1,const T & a2) { 4 //若滿足某個條件時,a1應該在a2前面,則返回true。 5 //否則返回false。 6 } 7 }; 8
例如:定義如下兩個規則
1 struct Rule1 //按從大到小排序 2 { 3 bool operator()( const int & a1,const int & a2) { 4 return a1 > a2; 5 } 6 }; 7 struct Rule2 //按個位數從小到大排序 8 { 9 bool operator()( const int & a1,const int & a2) { 10 return a1%10 < a2%10; 11 } 12 };
可以如下調用sort函數:
int a[] = { 12,45,3,98,21,7}; sort(a,a+sizeof(a)/sizeof(int)); //從小到大 sort(a,a+sizeof(a)/sizeof(int),Rule1( )); //從大到小 sort(a,a+sizeof(a)/sizeof(int),Rule2( )); //按個位數從小到大
用sort進行排序(用法四)----對結構體數組排序
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 struct Student { 6 char name[20]; 7 int id; 8 double gpa; 9 }; 10 Student students [] = { 11 {"Jack",112,3.4},{"Mary",102,3.8},{"Mary",117,3.9}, 12 {"Ala",333,3.5},{"Zero",101,4.0} }; 13 14 //當某個條件滿足時,s1應該在s2前面,則返回true;否則返回false。 15 struct StudentRule1//按姓名從小到大排 16 { bool operator( ) (const Student & s1,const Student & s2) 17 { if( strcmp(s1.name,s2.name) < 0)return true; 18 return false; 19 } 20 }; 21 struct StudentRule2//按id從小到大排 22 { bool operator( ) (const Student & s1,const Student & s2) 23 { return s1.id < s2.id; } 24 }; 25 struct StudentRule3 //按gpa從高到低排 26 { bool operator( ) (const Student & s1,const Student & s2) 27 { return s1.gpa > s2.gpa; } 28 }; 29 30 void PrintStudents(Student s[],int size){ 31 for(int i = 0;i < size;++i) 32 cout << "(" << s[i].name << ","<< s[i].id <<"," << s[i].gpa << ") " ; 33 cout << endl; 34 } 35 36 int main() 37 { 38 int n = sizeof(students) / sizeof(Student); 39 sort(students,students+n,StudentRule1( )); //按姓名從小到大排 40 PrintStudents(students,n); 41 sort(students,students+n,StudentRule2( )); //按id從小到大排 42 PrintStudents(students,n); 43 sort(students,students+n,StudentRule3( )); //按gpa從高到低排 44 PrintStudents(students,n); 45 return 0; 46 }
上述用法一至用法4的完整演示代碼如下:

1 #include<iostream> 2 #include<stdio.h> 3 #include<time.h> 4 #include<stdlib.h> 5 #include<string.h> 6 #include<algorithm> 7 using namespace std; 8 9 struct Student 10 { 11 char name[20]; 12 int id; 13 double gpa; 14 }; 15 16 17 18 //---------------------------------------------------------- 19 //當某個條件滿足時,a1應該在a2前面,則返回true;否則返回false。 20 struct Rule1 //按從大到小排序 21 { 22 bool operator()( const int & a1,const int & a2) 23 { 24 return a1 > a2; 25 } 26 }; 27 //當某個條件滿足時,a1應該在a2前面,則返回true;否則返回false。 28 struct Rule2 //按個位數從小到大排序 29 { 30 bool operator()( const int & a1,const int & a2) 31 { 32 return a1%10 < a2%10; 33 } 34 }; 35 //當某個條件滿足時,s1應該在s2前面,則返回true;否則返回false。 36 struct StudentRule1//按姓名從小到大排 37 { 38 bool operator() (const Student & s1,const Student & s2) 39 { 40 if( strcmp(s1.name,s2.name) < 0)return true; 41 return false; 42 } 43 }; 44 //當某個條件滿足時,s1應該在s2前面,則返回true;否則返回false。 45 struct StudentRule2//按id從小到大排 46 { 47 bool operator() (const Student & s1,const Student & s2) 48 { return s1.id < s2.id; } 49 }; 50 //當某個條件滿足時,s1應該在s2前面,則返回true;否則返回false。 51 struct StudentRule3 //按gpa從高到低排 52 { 53 bool operator() (const Student & s1,const Student & s2) 54 { return s1.gpa > s2.gpa; } 55 }; 56 57 58 59 60 61 //----------隨機數相關子函數----------------------------- 62 int getRandomInt(int a,int b)//返回[a,b]之間一個隨機整數 63 { return (rand() % (b-a+1))+ a; } 64 double getRandomDouble()//返回0~1之間隨機浮點數 65 { return rand()/double(RAND_MAX); } 66 char getUpChar()//返回隨機大寫字母 67 { return ((char)(rand()%26+'A')); } 68 char getDownChar()//返回隨機小寫字母 69 { return ((char)(rand()%26+'a')); } 70 void InitRandom() 71 { srand((unsigned)time(0)); } 72 //------------------------------------------------------- 73 void PrintStudents(Student s[],int size) 74 { 75 for(int i = 0;i < size;++i) 76 cout<< "(" << s[i].name << "," 77 << s[i].id <<"," << s[i].gpa << ") " ; 78 cout<<endl; 79 } 80 81 int main() 82 { 83 int IntArr[15],IntArr2[15],IntArr3[15],i,n=15; 84 double dArr[15]; 85 InitRandom(); 86 87 //------------------------------------------------------- 88 for(i=0;i<n;i++)//生成隨機整數數組 89 { 90 IntArr3[i]=IntArr2[i]=IntArr[i]=getRandomInt(1,99); 91 printf("%2d ",IntArr[i]); 92 } 93 printf("\n"); 94 //--------使用默認排序規則對基本類型從小到大排序從小到大排序----------------------------------------------- 95 sort(IntArr,IntArr+n);//默認從小到大排序 96 for(i=0;i<n;i++) 97 printf("%2d ",IntArr[i]); 98 printf("\n"); 99 100 sort(IntArr2,IntArr2+10);//對IntArr2[0]~IntArr2[9]從小到大排序 101 for(i=0;i<n;i++) 102 printf("%2d ",IntArr2[i]); 103 printf("\n"); 104 105 sort(IntArr3+2,IntArr3+10);//對IntArr3[2]~IntArr3[9]從小到大排序 106 for(i=0;i<n;i++) 107 printf("%2d ",IntArr3[i]); 108 printf("\n\n\n"); 109 //------------------------------------------------------- 110 111 112 113 114 115 //------------------------------------------------------- 116 n=10; 117 for(i=0;i<n;i++)//生成隨機浮點數數組 118 { 119 dArr[i]=getRandomDouble()*1000; 120 printf("%.2lf ",dArr[i]); 121 } 122 printf("\n"); 123 //------對基本數據類型從大到小排序------------------------- 124 sort(dArr+1,dArr+4,greater<double>());//對dArr[1]~dArr[3]從大到小排序 125 for(i=0;i<n;i++) 126 printf("%.2lf ",dArr[i]); 127 printf("\n\n\n"); 128 //------------------------------------------------------- 129 130 131 132 133 //-----使用自定義規則排序-------------------------------- 134 n=15; 135 sort(IntArr,IntArr+n); //默認從小到大 136 for(i=0;i<n;i++) printf("%2d ",IntArr[i]); 137 printf("\n"); 138 139 sort(IntArr,IntArr+n,Rule1()); //Rule1()規則從大到小 140 for(i=0;i<n;i++) printf("%2d ",IntArr[i]); 141 printf("\n"); 142 143 sort(IntArr,IntArr+n,Rule2()); //Rule2()規則按個位數從小到大 144 for(i=0;i<n;i++) printf("%2d ",IntArr[i]); 145 printf("\n\n\n"); 146 //------------------------------------------------------- 147 148 149 //--------自定義規則對結構體數組排序--------------------- 150 Student students[]= 151 { 152 {"Jack",112,3.4},{"Mary",102,3.8},{"Mary",117,3.9}, 153 {"Ala",333,3.5},{"Zero",101,4.0} 154 }; 155 n=sizeof(students)/sizeof(Student); 156 sort(students,students+n,StudentRule1()); //按姓名從小到大排 157 PrintStudents(students,n); 158 sort(students,students+n,StudentRule2()); //按id從小到大排 159 PrintStudents(students,n); 160 sort(students,students+n,StudentRule3()); //按gpa從高到低排 161 PrintStudents(students,n); 162 printf("\n\n\n"); 163 //------------------------------------------------------- 164 165 166 return 0; 167 }
上面第3、4種用法自定義排序規則使用的是運算符重載。其實可以按照sort函數里面關於cmp參數的規則,自己定義一個子函數來表示排序規則。下面第5種用法就是展示這種操作。
用sort進行排序(用法五)----子函數表示排序規則

1 #include<iostream> 2 #include<stdio.h> 3 #include<time.h> 4 #include<stdlib.h> 5 #include<string.h> 6 #include<algorithm> 7 using namespace std; 8 9 10 typedef struct 11 { 12 int No; 13 int yuWen,shuXue,yingYu,zongFen; 14 }stu; 15 typedef struct 16 { 17 int x,y; 18 }point; 19 20 21 //--------------------------------------------------------------- 22 bool cmp1(int a,int b)//對int數組從小到大排序.參數的類型應跟待排序數組元素類型一致 23 {//當某個條件滿足時,a應該在b前面,則返回true;否則返回false。 24 if(a<b)return true; 25 else return false; 26 //return a<b; //直接這樣寫更簡潔 27 } 28 bool cmp2(int a,int b)//對int數組從大到小排序.參數的類型應跟待排序數組元素類型一致 29 {//當某個條件滿足時,a應該在b前面,則返回true;否則返回false。 30 if(a>b)return true; 31 else return false; 32 //return a>b; //直接這樣寫更簡潔 33 } 34 bool cmp3(int a,int b)//對int數組按個位從大到小排序.參數的類型應跟待排序數組元素類型一致 35 {//當某個條件滿足時,a應該在b前面,則返回true;否則返回false。 36 return a%10 > b%10; //直接這樣寫更簡潔 37 } 38 bool cmp6(stu a,stu b)//對stu結構體類型數組排序.參數的類型應跟待排序數組元素類型一致 39 { //優先按總分從大到小,總分相等則按學號從小到大 40 //當某個條件滿足時,a應該在b前面,則返回true;否則返回false。 41 if(a.zongFen<b.zongFen)return false; 42 else if(a.zongFen>b.zongFen) return true; 43 else 44 { 45 if(a.No<b.No)return true; 46 else if(a.No>b.No) return false; 47 } 48 } 49 bool cmp7(point a,point b)//對point結構體類型數組元素排序.參數的類型應跟待排序數組元素類型一致 50 { //優先按x從小到大排序,當x相等則按y從大到小排序。 51 //當某個條件滿足時,a應該在b前面,則返回true;否則返回false。 52 if(a.x < b.x) return true; 53 else if(a.x > b.x)return false; 54 else 55 { 56 if(a.y > b.y)return true; 57 else if(a.y < b.y)return false; 58 } 59 } 60 bool cmp8(point a,point b)//對point結構體類型數組元素排序.參數的類型應跟待排序數組元素類型一致 61 { //優先按x從大到小排序。 62 //當某個條件滿足時,a應該在b前面,則返回true;否則返回false。 63 return a.x>b.x; 64 } 65 66 67 68 //----------隨機數相關子函數----------------------------- 69 int getRandomInt(int a,int b)//返回[a,b]之間一個隨機整數 70 { return (rand() % (b-a+1))+ a; } 71 double getRandomDouble()//返回0~1之間隨機浮點數 72 { return rand()/double(RAND_MAX); } 73 char getUpChar()//返回隨機大寫字母 74 { return ((char)(rand()%26+'A')); } 75 char getDownChar()//返回隨機小寫字母 76 { return ((char)(rand()%26+'a')); } 77 void InitRandom() 78 { srand((unsigned)time(0)); } 79 80 81 int main() 82 { 83 int IntArr[15],IntArr2[15],IntArr3[15],i,n=15; 84 double dArr[15]; 85 stu stuArr[50];//每個元素表示一個學生的數據 86 point pArr[50];//每個元素表示一個整數點的數據(x,y) 87 InitRandom(); 88 89 //------------------------------------------------------- 90 for(i=0;i<n;i++)//生成隨機整數數組 91 { 92 IntArr3[i]=IntArr2[i]=IntArr[i]=getRandomInt(1,99); 93 printf("%2d ",IntArr[i]); 94 } 95 printf("\n"); 96 //--------使用默認排序規則對基本類型從小到大排序從小到大排序----------------------------------------------- 97 sort(IntArr,IntArr+n);//默認從小到大排序 98 for(i=0;i<n;i++) 99 printf("%2d ",IntArr[i]); 100 printf("\n"); 101 102 sort(IntArr2,IntArr2+10);//對IntArr2[0]~IntArr2[9]從小到大排序 103 for(i=0;i<n;i++) 104 printf("%2d ",IntArr2[i]); 105 printf("\n"); 106 107 sort(IntArr3+2,IntArr3+10);//對IntArr3[2]~IntArr3[9]從小到大排序 108 for(i=0;i<n;i++) 109 printf("%2d ",IntArr3[i]); 110 printf("\n\n\n"); 111 112 113 114 //------------------------------------------------------- 115 n=10; 116 for(i=0;i<n;i++)//生成隨機浮點數數組 117 { 118 dArr[i]=getRandomDouble()*1000; 119 printf("%.2lf ",dArr[i]); 120 } 121 printf("\n"); 122 //------對基本數據類型從大到小排序------------------------- 123 sort(dArr+1,dArr+4,greater<double>());//對dArr[1]~dArr[3]從大到小排序 124 for(i=0;i<n;i++) 125 printf("%.2lf ",dArr[i]); 126 printf("\n\n\n"); 127 128 129 130 131 //-----使用自定義規則排序-------------------------------- 132 n=15; 133 sort(IntArr,IntArr+n); //默認從小到大 134 for(i=0;i<n;i++) printf("%2d ",IntArr[i]); 135 printf("\n"); 136 137 sort(IntArr,IntArr+n,cmp2); //cmp2()規則從大到小 138 for(i=0;i<n;i++) printf("%2d ",IntArr[i]); 139 printf("\n"); 140 141 sort(IntArr,IntArr+n,cmp1); //cmp1()規則從小到大 142 for(i=0;i<n;i++) printf("%2d ",IntArr[i]); 143 printf("\n"); 144 145 sort(IntArr,IntArr+n,cmp3); //cmp3()規則按個位數從大到小 146 for(i=0;i<n;i++) printf("%2d ",IntArr[i]); 147 printf("\n\n\n"); 148 149 150 //--------自定義規則對結構體數組排序--------------------- 151 n=10; 152 for(i=0;i<n;i++)//生成stu結構體類型的隨機數據 153 { 154 stuArr[i].No=1000+i; 155 stuArr[i].yuWen=getRandomInt(90,150); 156 stuArr[i].shuXue=getRandomInt(90,150); 157 stuArr[i].yingYu=getRandomInt(90,150); 158 stuArr[i].zongFen=stuArr[i].yuWen+stuArr[i].shuXue+stuArr[i].yingYu; 159 printf("%d %3d %3d %3d %3d\n",stuArr[i].No,stuArr[i].yuWen,stuArr[i].shuXue,stuArr[i].yingYu,stuArr[i].zongFen); 160 } 161 printf("\n"); 162 //------------------------------------------------------- 163 sort(stuArr,stuArr+n,cmp6);//對stu類型數組排序 164 for(i=0;i<n;i++) 165 printf("%d %3d %3d %3d %3d\n",stuArr[i].No,stuArr[i].yuWen,stuArr[i].shuXue,stuArr[i].yingYu,stuArr[i].zongFen); 166 printf("\n\n\n"); 167 168 169 170 171 //------------------------------------------------------- 172 n=10; 173 for(i=0;i<n;i++)//生成point結構體類型的隨機數據 174 { 175 pArr[i].x=getRandomInt(80,100); 176 pArr[i].y=getRandomInt(1,100); 177 printf("%2d %2d\n",pArr[i].x,pArr[i].y); 178 } 179 printf("\n"); 180 //------------------------------------------------------- 181 sort(pArr,pArr+n,cmp7);//對point類型數組排序 182 for(i=0;i<n;i++) 183 printf("%2d %2d\n",pArr[i].x,pArr[i].y); 184 printf("\n"); 185 186 stable_sort(pArr,pArr+n,cmp8);//對point類型數組排序,穩定排序 187 for(i=0;i<n;i++) 188 printf("%2d %2d\n",pArr[i].x,pArr[i].y); 189 printf("\n\n\n"); 190 191 192 193 return 0; 194 }