Bootstrap

C++之sort()函数详解

        顾名思义,sort就是用来排序的函数,它根据具体情形使用不同的排序方法,效率较高。一般来说,不推荐使用C语言中的qsort函数,原因是qsort用起来比较烦琐,涉及很多指针的操作。而且sort在实现中规避了经典快速排序中可能出现的会导致实际复杂度退化到(o(n^{2})的极端情况。希望读者能通过这篇介绍来轻松愉快地使用sort函数。
1.如何使用sort排序
        sort函数的使用必须加上头文件“#include<algorithm>”和“using namespace std;”,其使用的方式如下:
        sort(首元素地址(必填),尾元素地址的下一个地址(必填),比较函数(非必填));
可以看到,sort的参数有三个,其中前两个是必填的,而比较函数则可以根据需要填写,如果不写比较函数,则默认对前面给出的区间进行递增排序。


   
   
  1. #include <stdio.h>
  2. #include <algorithm>
  3. using namespace std;
  4. int main(){
  5. int a[ 6] = { 9, 4, 2, 5, 6, -1};
  6. sort(a,a+ 4);
  7. //a[0]~a[3]从小到大排序
  8. for( int i= 0;i< 6;i++){
  9. printf( "%d",a[i]);
  10. }
  11. printf( "\n");
  12. //a[0]~a[5]从小到大排序
  13. sort(a,a+ 6);
  14. for( int i= 0;i< 6;i++){
  15. printf( "%d",a[i]);
  16. }
  17. return 0;
  18. }

        运行之后可以得到下面的结果,可以试着理解一下(特别注意理解“尾元素地址的下一个地址”)。输出结果:


   
   
  1. 24596 -1
  2. -124569

 又如,对double型数组排序:


   
   
  1. #include <stdio.h>
  2. #include <algorithm>
  3. using namespace std;
  4. int main(){
  5. double a[] = { 1.1, -1.1, 99};
  6. sort(a,a+ 3);
  7. for( int i= 0;i< 3;i++){
  8. printf( "%.1f",a[i]);
  9. }
  10. return 0;
  11. }

 输出结果:

-1.1 1.1 99.0
   
   

再如,对char数组排序(默认为字典序) 


   
   
  1. #include <stdio.h>
  2. #include <algorithm>
  3. using namespace std;
  4. int main(){
  5. char c[]={ 'I', 'L', 'O', 'V', 'E', 'U'};
  6. sort(c,c+ 6);
  7. for( int i= 0;i< 6;i++){
  8. printf( "%c",c[i]);
  9. }
  10. return 0;
  11. }

 输出结果:

EILOUV
   
   

 2.如何实现比较函数cmp

        下面介绍对于基本数据类型、结构体类型、STL容器进行自定义排序cmp的写法。

        2.1基本数据类型数组的排序

若比较函数不填,默认升序排序 ,下面为对int数组的排序:


   
   
  1. #include <stdio.h>
  2. #include <algorithm>
  3. using namespace std;
  4. int main(){
  5. int a[ 5] = { 3, 5, 2, 1, 4};
  6. sort(a,a+ 5);
  7. for( int i= 0;i< 5;i++){
  8. printf( "%d",a[i]);
  9. }
  10. return 0;
  11. }

  输出结果:

12345
   
   

 如果想要降序排列,则需要使用cmp函数“告诉”sort何时交换元素,可以这样写:


   
   
  1. #include <stdio.h>
  2. #include <algorithm>
  3. using namespace std;
  4. bool cmp(int a,int b){
  5. return a>b;
  6. //可以理解为a>b时,把a放在前面
  7. }
  8. int main(){
  9. int a[ 5] = { 3, 5, 2, 1, 4};
  10. sort(a,a+ 5,cmp);
  11. for( int i= 0;i< 5;i++){
  12. printf( "%d",a[i]);
  13. }
  14. return 0;
  15. }

  输出结果:

54321
   
   

        这样就可以让数值大的元素在前面,即降序排列,对于double,char亦如此,把cmp内传入参数的类型改变一下就好了。

        2.2结构体数组的排序

        现在定义了如下结构体:


   
   
  1. struct node{
  2. int x,y;
  3. }ssd[ 10];

如果想让ssd数组按照x从大到小排列,可以这样写cmp函数:


   
   
  1. bool cmp(node a, node b){
  2. return a.x > b.x;
  3. }

示例如下:


   
   
  1. #include <stdio.h>
  2. #include <algorithm>
  3. using namespace std;
  4. struct node{
  5. int x,y;
  6. }ssd[ 10];
  7. bool cmp(node a, node b){
  8. return a.x > b.x; //按照x降序排列
  9. }
  10. int main(){
  11. ssd[ 0].x= 2; //{2,2}
  12. ssd[ 0].y= 2;
  13. ssd[ 1].x= 1; //{1,3}
  14. ssd[ 1].y= 3;
  15. ssd[ 2].x= 3; //{3,1}
  16. ssd[ 2].y= 1;
  17. sort(ssd,ssd+ 3,cmp);
  18. for( int i= 0;i< 3;i++){
  19. printf( "%d %d\n",ssd[i].x,ssd[i].y);
  20. }
  21. return 0;
  22. }

 输出结果:


   
   
  1. 3 1
  2. 2 2
  3. 1 3

 如果想先按照x降序,x相等时,y升序排列(二级排序),那么:


   
   
  1. #include <stdio.h>
  2. #include <algorithm>
  3. using namespace std;
  4. struct node{
  5. int x,y;
  6. }ssd[ 10];
  7. bool cmp(node a, node b){
  8. if(a.x!=b.x) return a.x>b.x;
  9. else return a.y < b.y; //按照x降序排列
  10. }
  11. int main(){
  12. ssd[ 0].x= 2; //{2,2}
  13. ssd[ 0].y= 2;
  14. ssd[ 1].x= 1; //{1,3}
  15. ssd[ 1].y= 3;
  16. ssd[ 2].x= 2; //{2,1}
  17. ssd[ 2].y= 1;
  18. sort(ssd,ssd+ 3,cmp);
  19. for( int i= 0;i< 3;i++){
  20. printf( "%d %d\n",ssd[i].x,ssd[i].y);
  21. }
  22. return 0;
  23. }

 输出结果:


   
   
  1. 2 1
  2. 2 2
  3. 1 3

         2.3容器的排序

        在STL标准容器中,只有vector、string、deque可以使用sort。这是因为像set,map这种容器是用红黑树实现的,元素本身有序,因此不允许使用sort排序。

下面以vector为例:


   
   
  1. #include <stdio.h>
  2. #include <vector>
  3. #include <algorithm>
  4. using namespace std;
  5. bool cmp(int a,int b){
  6. return a>b;
  7. }
  8. int main(){
  9. vector< int> vi;
  10. vi. push_back( 3);
  11. vi. push_back( 1);
  12. vi. push_back( 2);
  13. sort(vi. begin(),vi. end(),cmp); //整个排序
  14. for( int i= 0;i< 3;i++){
  15. printf( "%d ",vi[i]);
  16. }
  17. return 0;
  18. }

 输出结果:

3 2 1
   
   

;