知识点小结
对于排序问题,我们可以自己写基于不同原理的排序方法,如冒泡排序,快排等。但在实际应用中,我们不可能每次都自己写排序,这里我们可以C++在algorithm包中定义好的sort()函数进行排序。但是,不论我们是自己手写排序,还是使用已有的sort函数,在面对复杂的数据类型,比如自己定义的结构体时,我们就有必要自己定义一个比较器,否则无法进行排序。对于sort()函数来说,其默认是按升序排序,我们可以自定义比较器来改变它。代码如下。
#include <iostream>
#include <algorithm>
//需要引入algorithm头文件,因为sort()函数包含在这个头文件里
using namespace std;
struct student
{
string name;
int socre;
int id;
};
bool stuid_cmp(student &st1, student &st2)
{
return st1.id > st2.id;
}
int main()
{
student stlist[] = {
{"jack", 85, 1},
{"kalvin", 86, 3},
{"taffy", 78, 2}
};
sort(stlist, stlist+3, stuid_cmp);
for(int i=0; i<3; i++)
cout << stlist[i].id <<" " << stlist[i].name
<<" " << stlist[i].socre << endl;
return 0;
}
运行结果如下所示:
以上是单独写了一个比较器的方法,这种方法对于sort这类可以接受一个bool类型的值作为排序标准的函数比较适用。但是在今后的使用过程中,我们还会遇到诸如将复杂数据类型放入堆等的数据结构中的情况。每次单独重写比较器不是那么直观,我们可以直接在结构体当中就定义比较顺序。这里就涉及到运算符的重载。需要对运算符进行重载的原因,是基本的运算符是不能够比较复杂的结构体的,重载后相当于告知运算符如何比较自定义的结构体。具体来看下面的代码:
#include <iostream>
#include <algorithm>
using namespace std;
struct student
{
string name;
int score;
int id;
//重载<号,使得<号能够比较结构体,也可定义成反序
bool operator<(const student& st1)const
{
return score < st1.score;
}
};
int main()
{
student stlist[] = {
{"jack", 85, 1},
{"kalvin", 86, 3},
{"taffy", 78, 2}
};
//这里由于已经在结构体声明时就定义了如何比较大小,所以
//sort函数就不需要再传入第三个参数了
sort(stlist, stlist+3);
for(int i=0; i<3; i++)
cout << stlist[i].id <<" " << stlist[i].name
<<" " << stlist[i].score << endl;
return 0;
}