<algorithm>中sort()函数的用法

   先说一下,本篇文章我没有讲sort()实现排序的原理,我写在另一篇文章中了,如果想了解的话,可以看一下,附上链接:https://www.cnblogs.com/buanxu/p/12772700.html

   sort(v.begin(),v.end(),cmp),它是用来对一组序列进行排序的;有三个参数,前两个参数是待排序区间;第三个参数可有可无(第三个参数代表比较规则),

没有第三个参数的时候,sort()默认按升序排列,有第三个参数的时候,可以通过这个参数实现各种各样的排序,包括降序。sort()函数功能强大就是强大在

第三个参数,后面会讲到。

   sort()函数除了可以对int型、char型、double型、字符串排序外,还可以实现对结构体、链表、pair、vector、等类型进行排序,但需要自己写比较函数,后面

也会讲到。而且sort()既可以对数组排序,也可以对vector容器排序。下面就先说一下sort()只有两个参数时的用法,看代码吧,写的比较详细,列举了多种情况

 1 #include<iostream>
 2 #include<vector>
 3 #include<string>
 4 #include<algorithm>
 5 using namespace std;
 6 int main()
 7 {
 8     int a[10]={6,5,4,8,3,9,7,10,1,2};
 9     char b[8]={'h','z','l','n','m','r','d','g'};
10     vector<double> v1;
11     vector<string> v2;
12     v1.push_back(3.6);
13     v1.push_back(0.8);
14     v1.push_back(-0.5);
15     v1.push_back(-2.4);
16     v1.push_back(1.2);
17     v2.push_back("abcde");
18     v2.push_back("fdbcde");
19     v2.push_back("apcde");
20     v2.push_back("fdbcdc");
21     v2.push_back("fdbc");
22 
23     cout<<"对a排序前:";
24     for(int i=0;i<10;i++)
25         cout<<a[i]<<" ";
26     cout<<"
对a排序后:";
27     sort(a+1,a+9);    //可以指定任意合法的排序区间,不能越界
28     for(int i=0;i<10;i++)
29         cout<<a[i]<<" ";
30 
31     cout<<"

对b排序前:";
32     for(int i=0;i<8;i++)
33         cout<<b[i]<<" ";
34     cout<<"
对b排序后:";
35     sort(b,b+8);     //对整个b排序
36     for(int i=0;i<8;i++)
37         cout<<b[i]<<" ";
38 
39     cout<<"

对v1排序前:";
40     for(int i=0;i<v1.size();i++)
41         cout<<v1[i]<<" ";
42     cout<<"
对v1排序后:";
43     sort(v1.begin(),v1.end());
44     for(int i=0;i<v1.size();i++)
45         cout<<v1[i]<<" ";
46 
47     cout<<"

对v2排序前:";
48     for(int i=0;i<v2.size();i++)
49         cout<<v2[i]<<" ";
50     cout<<"
对v2排序后:";
51     sort(v2.begin(),v2.end());
52     for(int i=0;i<v2.size();i++)
53         cout<<v2[i]<<" ";
54     cout<<"
";
55     return 0;
56 }

结果如下:

 

上面列举了几种常见数据类型排序后的结果,但是它们都是按升序排列的,要想按降序排列,有3种方法。为了给大家讲的更详细一点,在第一个方法中我

用了好几种数据类型;后面两种方法就只用了一种数据类型,以减少篇幅。

1. sort()函数只有两个参数时默认升序排列,在排完序后,再用reverse()函数把整个序列给翻转一下,这样序列就变成了降序;把上面的代码改一下就好了

 1 #include<iostream>
 2 #include<vector>
 3 #include<string>
 4 #include<algorithm>
 5 using namespace std;
 6 int main()
 7 {
 8     int a[10]={6,5,4,8,3,9,7,10,1,2};
 9     char b[8]={'h','z','l','n','m','r','d','g'};
10     vector<double> v1;
11     vector<string> v2;
12     v1.push_back(3.6);
13     v1.push_back(0.8);
14     v1.push_back(-0.5);
15     v1.push_back(-2.4);
16     v1.push_back(1.2);
17     v2.push_back("abcde");
18     v2.push_back("fdbcde");
19     v2.push_back("apcde");
20     v2.push_back("fdbcdc");
21     v2.push_back("fdbc");
22 
23     cout<<"对a排序前:";
24     for(int i=0;i<10;i++)
25         cout<<a[i]<<" ";
26     cout<<"
对a默认排序后:";
27     sort(a+1,a+9);    //可以指定任意合法的排序区间,不能越界
28     for(int i=0;i<10;i++)
29         cout<<a[i]<<" ";
30     cout<<"
对a降序排序后:";
31     reverse(a+1,a+9);
32     for(int i=0;i<10;i++)
33         cout<<a[i]<<" ";
34 
35     cout<<"

对b排序前:";
36     for(int i=0;i<8;i++)
37         cout<<b[i]<<" ";
38     cout<<"
对b默认排序后:";
39     sort(b,b+8);     //对整个b排序
40     for(int i=0;i<8;i++)
41         cout<<b[i]<<" ";
42     cout<<"
对b降序排序后:";
43     reverse(b,b+8);
44     for(int i=0;i<8;i++)
45         cout<<b[i]<<" ";
46 
47     cout<<"

对v1排序前:";
48     for(int i=0;i<v1.size();i++)
49         cout<<v1[i]<<" ";
50     cout<<"
对v1排序后:";
51     sort(v1.begin(),v1.end());
52     for(int i=0;i<v1.size();i++)
53         cout<<v1[i]<<" ";
54     cout<<"
对v1默认排序后:";
55     reverse(v1.begin(),v1.end());
56     for(int i=0;i<v1.size();i++)
57         cout<<v1[i]<<" ";
58 
59     cout<<"

对v2排序前:";
60     for(int i=0;i<v2.size();i++)
61         cout<<v2[i]<<" ";
62     cout<<"
对v2排序后:";
63     sort(v2.begin(),v2.end());
64     for(int i=0;i<v2.size();i++)
65         cout<<v2[i]<<" ";
66     cout<<"
对v2默认排序后:";
67     reverse(v2.begin(),v2.end());
68     for(int i=0;i<v2.size();i++)
69         cout<<v2[i]<<" ";
70     cout<<"
";
71     return 0;
72 }

结果如下:

可以看到,在用reverse()翻转后就变成了降序,这里提醒一下,为了节省篇幅,让大家看起来更流畅,下面两个方法都将只使用一种数据类型了,以减少代码长度

2. 除了用reverse()翻转外,还可以借助c++标准库来实现降序(或升序)。此时要包含头文件<functional>,<functional>头文件提供了一些基于模板的比较函数对象,

    这里在排序的时候只用到了  greater<type>() 和 less<type>() 两个;让 greater<type>() 或 less<type>() 做sort()函数的第三个参数来实现升序或降序排列;其中

    greater<type>() 用于降序排列,less<type>() 用于升序排列,具体用法看代码

 1 #include<iostream>
 2 #include<functional>
 3 #include<algorithm>
 4 using namespace std;
 5 int main()
 6 {
 7     int a[10]={6,5,4,8,3,9,7,10,1,2};
 8 
 9     cout<<"对a排序前:";
10     for(int i=0;i<10;i++)
11         cout<<a[i]<<" ";
12 
13     cout<<"
对a降序排列后:";
14     sort(a,a+10,greater<int>());
15     for(int i=0;i<10;i++)
16         cout<<a[i]<<" ";
17 
18     cout<<"
对a升序排列后:";
19     sort(a,a+10,less<int>());
20     for(int i=0;i<10;i++)
21         cout<<a[i]<<" ";
22     cout<<"
";
23     return 0;
24 }

结果如下图:

3. 第三个方法是自己写一个比较函数来实现升序或降序排列,并让这个比较函数做sort()函数的第三个参数;其实比较函数不仅能实现升序降序排列,还能实现其他的功能。

    这就是sort()函数功能强大的地方,它可以扩展,而扩展的关键就是第三个参数,所以我把这种方法放在最后讲。

    先说一下比较函数吧,当你想实现特定比较方式的时候,就要自己定义一个返回bool值的比较函数了;这时sort()函数的第三个参数就是一个函数,如果它返回假值就交换

    操作对象的位置,返回真值的话操作对象位置不变。下面就用比较函数来实现升序降序的排列,看代码

 1 #include<iostream>
 2 #include<functional>
 3 #include<algorithm>
 4 using namespace std;
 5 bool cmp1(int a,int b)  //按降序排列
 6 {
 7     return a>b;
 8 }
 9 
10 bool cmp2(int a,int b)  //按升序排列
11 {
12     return a<b;
13 }
14 int main()
15 {
16     int a[10]={6,5,4,8,3,9,7,10,1,2};
17 
18     cout<<"对a排序前:";
19     for(int i=0;i<10;i++)
20         cout<<a[i]<<" ";
21 
22     cout<<"
对a降序排列后:";
23     sort(a,a+10,cmp1);   //这里不需要对比较函数cmp1传入参数
24     for(int i=0;i<10;i++)
25         cout<<a[i]<<" ";
26 
27     cout<<"
对a升序排列后:";
28     sort(a,a+10,cmp2);   ////不需要对比较函数cmp2传入参数
29     for(int i=0;i<10;i++)
30         cout<<a[i]<<" ";
31     cout<<"
";
32     return 0;
33 }

结果看下图:

这里对比较函数的原理介绍一下: bool cmp(int a, int b);在定义这个比较函数的时候要明确比较对象的数据类型,这里是int型,也可以是其他的任意类型,比如结构体、vector、链表等。

但是在使用的时候(即做sort()函数的第三个参数时)不用对cmp传入参数,这是需要注意的地方。下面就是比较原理了

bool cmp(int a,int b)  
{
 return a>b;
}

sort(a,a+10,cmp);

sort() 操作的对象数组或vector中两个挨着的顺序元素分别赋值到a和b上,通过一系列操作(这个操作就是你写的比较函数要实现的功能)后,返回bool值。

上面的sort()函数都是对简单的数据类型进行排序,那之前也说过,sort()还可以对结构体、链表、vector等排序,不过还是要你自己去写比较函数的。这里就用结构体举例了,

下面通过一道题来体现比较函数的强大功能,这是之前我刷过的PTA的一道题。题目如下

其实这道题就要用到比较函数,用比较函数来实现sort()对结构体的排序,而且这里的比较函数要比之前写的比较函数cmp1和cmp2复杂点,并且比较对象都是结构体。

下面只贴出了封装的结构体和比较函数的代码

 1 struct student{
 2     int id,dscore,cscore;
 3     int sum;//总分
 4 };
 5 bool cmp(student a,student b)
 6 {    //按降序排列
 7     if(a.sum!=b.sum)
 8         return a.sum>b.sum; //优先按总分的高低排序
 9     else if(a.dscore!=b.dscore)
10         return a.dscore>b.dscore; //总分相同则优先按德分排序
11     else
12         return a.id<b.id; //总分和德分都相同则按学号排序
13 }

本题我在  “PTA刷题” 随笔里面详细讲到了,里面有完整代码,想看的可以去看一下,附上链接:

本人还正在学习中,水平有限,如果哪里写的不当,还请指出,谢谢哈 !

原文地址:https://www.cnblogs.com/buanxu/p/12771502.html