C++的sort函數


參考:

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++標准庫中。

函數原型

Sort(start,end,cmp)

參數

(1)start表示要排序數組的起始地址;
(2)end表示數組 結束地址的下一位
(3) cmp用於規定排序的方法,可不填,默認升序

功能

sort函數用於C++中,對給定區間所有元素進行排序,默認為升序,也可進行降序排序。
一般是直接對數組進行排序,例如 對基本類型的數組a[10]排序,sort(a,a+10)。而sort函數的強大之處在可與自定義的子函數cmp函數結合使用,即排序方法的選擇。

關於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 }
View Code

上面第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 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM