如何在 sort() 或 priori_queue 中 自定义 排序

总结一下:

核心区别在于: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<<pq.top().val<<" "<<pq.top().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 << q.top().name << " is " << q.top().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模板实现规定的,记住吧皮卡丘

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值