总结一下:
核心区别在于:sort()是 实例越小,排序越靠前;priority_queue是 实例越大,排序越靠前
由于这两个实现方式都是 关于 “小于” 操作的 ;
重载小于号:bool operator< (实例 m ) { return XXX } 的含义是: 若XXX,那么 当前this < 实例 m
传递函数都是 bool cmp( 实例 a , 实例 b) {return XXX } 的含义是 :若XXX,那么 实例a < 实例 b
因此,不同之处就是,我们判断出了啥时候实例 a 小于 实例 b :对于sort()实例小的排在前面,对于priority_queue() 实例小的排在后面 罢了
一、在sort() 中自定义排序:
有多种方法,我们主要条两种常用的:
第一种:重载 < 号
-- 这种适用于我们可以自定义数据结构的情况,因为重载函数需要定义在结构体中
核心就是:
① 明确对于sort()来说,他自带的运算符是 “<” 运算符,因此,我们能且只能重载这个小于运算符(若试图重载 > 运算符会报错,因为sort() 中根本没有定义这个 大于运算符)
② 解释一下 return stu.age > this->age ; 当 stu.age > this->age 时 (为true时),this 小于 stu ,由于对于sort:越小的越排在前面,因此,==》合起来就是:实例.age值越小,那么这个实例就越小,由于 sort 将小的实例排在前面,因此,--》 age 值越小,排序越靠前
③代码书写时注意 : bool operator < ; 参数都是 const 修饰, 最好加上& 做修饰
#include <iostream>
#include <algorithm>
using namespace std;
struct Student {
string name;
int num;
int age;
bool operator<(const Student &stu) const {
if(stu.age==this->age) return this->num<stu.num;
return stu.age > this->age;
}
};
int main() {
Student stu[5] = {{"Zhang san", 1, 18}, {"Li Si", 2, 21}, {"Wang Er", 3, 20},
{"Ma Zi", 4, 21}, {"Lucy", 5, 17}};
sort(stu, stu + 5);
for (int i = 0; i < 5; ++i) {
cout << stu[i].name << " is " << stu[i].age << endl;
}
return 0;
}
输出:
Lucy is 17
Zhang san is 18
Wang Er is 20
Li Si is 21
Ma Zi is 21
第二种:写一个比较函数,参数是两个要排序的结构体类型变量
-- 这种 就 适用于 **结构体并非由自己定义** 的情况:此时就需要额外传入一个比较函数作为参数了
#include <iostream>
#include <algorithm>
using namespace std;
struct Student {
string name;
int num;
int age;
};
bool cmp(const Student a, const Student b)
{
if(a.age==b.age) return a.num>b.num;
return a.age<b.age;
}
int main() {
Student stu[5] = {{"Zhang san", 1, 18}, {"Li Si", 2, 21}, {"Wang Er", 3, 20},
{"Ma Zi", 4, 21}, {"Lucy", 5, 17}};
sort(stu, stu + 5,cmp);
// 按照 age 从小到大输出,若age 相同,那么,按照num 从大到小输出
for (int i = 0; i < 5; ++i) {
cout << stu[i].name << " is " << stu[i].age << endl;
}
return 0;
}
解释一下:return a.age<b.age ; 的含义:当a的age 小于 b的age时,a 的优先级 大于 b 的优先级, 即, a排在b前面
【简单点说】:我们定义出 cmp这个函数时,参数是 ( const Student a, const Student b) 就直接暗含了一个定义:若 XXXXX ,那么,实例 a < 实例 b
二、在priority_queue() 中自定义排序:
而 priority_queue的优先级方式与sort正好完全相反:priority_queue 默认是大顶堆,即,最大值放在top(),
第一种方法也是 重载小于号:
#include <iostream>
#include <queue>
using namespace std;
struct Status{
int val,num;
Status(int a,int b){val=a,num=b;}
bool operator < (const Status &tmp) const{
if(val==tmp.val) return num < tmp.num;
return val > tmp.val;
}
};
int main() {
priority_queue<Status> pq;
pq.push(Status(9,2));
pq.push(Status(3,4));
pq.push(Status(3,7));
cout<<().val<<" "<<().num<<endl;
return 0;
}
【注意】虽然 priority_queue重载的也是小于号,但此时 判断式子返回 true 含义是 满足时,优先级小
解释一下 return val > tmp.val ; 那么,当前实例 小于 tmp 实例,由于priority_queue的实现是把大的放前,因此,当前实例比 tmp实例小,放在后面
因此:val 值越大,越放在后面
第二种是 cmp 作为参数传到 priority_queue中 :
含义依旧是:bool operator()( 实例a , 实例 b) { return XXX } 若XXX,那么,实例a 小于 实例 b
#include <iostream>
#include <queue>
using namespace std;
struct Student {
string name;
int num;
int age;
};
struct cmp {
bool operator()(const Student &stu1, const Student &stu2) {
return stu2.age < stu1.age;
}
};
int main() {
Student stu[5] = {{"Zhang san", 1, 18}, {"Li Si", 2, 19}, {"Wang Er", 3, 20},
{"Ma Zi", 4, 21}, {"Lucy", 5, 17}};
priority_queue<Student, vector<Student>, cmp> q;
for (int i = 0; i < 5; ++i) {
q.push(stu[i]);
}
//age越小越靠前
while (!q.empty()) {
cout << ().name << " is " << ().age << endl;
q.pop();
}
return 0;
}
【注意】重点解释一下这个写法吧:我们此时传递的cmp不再是一个函数而是一个结构体,里面包含了 bool operator() 函数,相当于重载了运算符 () ,与重载 < 含义类似
写法对应如下,注意 数据类型:
bool operator() (const AAA &a, const AAA &b ){ .... }
在将cmp结构体传入的时候,priority_queue()参数如下:
priority_queue<AAA, vector<AAA>,cmp> p;
【注意这里】第二个参数为啥要是vector<AAA>类型呢?没有为啥,这是priority_queue模板实现规定的,记住吧皮卡丘