服务端视角的C++从入门到精通(五)

89 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情

优先队列的简单用法

priority_queue这个模板类的第二个参数是底层实际的存储类型,第三个参数是仿函数。当然,其实也不只可以使用基本数据类型构造优先队列,使用结构体、甚至是类来构造优先队列都是可以的。原因也很简单,这就是template的好处了,那就是足够地抽象,以至于都可以忽略底层的数据类型,只要这个类型可以实现比较大小就可以了。让一个类实现比较大小,在C++里面主要有以下这么几种做法。第一种是在类或者结构体的内部重载友元运算符<即可,具体的代码如下:

struct Apple {
    std::string name;
    int price;

    friend bool operator < (const Apple &a1, const Apple &f2) {
        return a1.price > a2.price;
    }
};

这段代码中要注意的是,只能重载<,重载<是会报错的。这里如果使用priority_queue<Apple>这种方式构造优先队列,那么就默认是从小到大排序。其实有一种我个人认为很好记的方式,就是重载运算符的符号和里面return的符号是相反的,那么意味着使用的成员越大、结构体本身越小,成一种类似于负相关的关系,然后优先队列默认是大顶堆(less),所以每次使用top取到的结构体都具有最小的成员。还有一种方式,如下所示:

struct cmp {
    bool operator () (const Apple &a1, const Apple &a2) {
        return a1.price > a2.price;
    }
};

如果使用上面这种cmp仿函数的话,就需要priority_queue<Apple, std::vector<Apple>, cmp>这么写,作用的话,和第一种方式一样。理解方式也和第一种类似,因为符号是反着的,所以结构体的大小与成员的大小是负相关,默认大顶堆,所以每次取得的Apple都具有最小的price。还有一种是基于lambda表达式的方式,下篇文章中将详细进行讲解。