如何让C++ priority_queue基于自定义类age字段排序(升序/降序)
嘿,这个问题我刚好有经验,咱们一步步来解决它~
首先得明确:std::priority_queue 默认是大顶堆(降序排列),但它自带的std::less<T>比较器对Person*只会比较指针地址,完全不是你要的按age字段排序逻辑,所以必须自定义排序规则。
下面分两种排序需求,给你具体的实现方案:
1. 自定义比较器的两种写法
因为你存的是Person*,所以比较器要处理指针类型的对比,这里有两种常用方式:
方式一:用结构体作为比较器(最通用,兼容所有C++版本)
先定义专门的比较器结构体,分别实现降序和升序逻辑:
#include <queue> #include <vector> #include <string> #include <iostream> class Person { public: std::string name; int height; int age; // 加个构造函数方便测试 Person(std::string n, int h, int a) : name(n), height(h), age(a) {} }; // 降序比较器:age越大,优先级越高(符合默认大顶堆逻辑) struct AgeDescendComp { bool operator()(const Person* a, const Person* b) const { // 返回true表示a的优先级低于b,b会被排到前面 return a->age < b->age; } }; // 升序比较器:age越小,优先级越高(小顶堆) struct AgeAscendComp { bool operator()(const Person* a, const Person* b) const { return a->age > b->age; } };
然后你定义存放优先级队列的vector时,要明确指定模板参数:
// 存放降序优先级队列的vector std::vector<std::priority_queue<Person*, std::vector<Person*>, AgeDescendComp>> personsDesc; // 存放升序优先级队列的vector std::vector<std::priority_queue<Person*, std::vector<Person*>, AgeAscendComp>> personsAsc;
方式二:用lambda表达式(C++11及以后可用,更灵活)
如果不想写单独的结构体,可以用lambda直接定义比较逻辑,不过要注意模板参数的推导:
// 定义升序用的lambda auto ageAscendLambda = [](const Person* a, const Person* b) { return a->age > b->age; }; // 用decltype推导lambda的类型,定义优先级队列别名 using AscPQ = std::priority_queue<Person*, std::vector<Person*>, decltype(ageAscendLambda)>; // 初始化vector里的优先级队列时,要把lambda传进去 std::vector<AscPQ> personsAsc; personsAsc.emplace_back(ageAscendLambda);
2. 测试验证示例
写个小代码验证一下排序效果:
int main() { // 测试降序队列 std::priority_queue<Person*, std::vector<Person*>, AgeDescendComp> pqDesc; pqDesc.push(new Person("Alice", 165, 25)); pqDesc.push(new Person("Bob", 180, 30)); pqDesc.push(new Person("Charlie", 175, 20)); std::cout << "降序输出(age大的优先):" << std::endl; while (!pqDesc.empty()) { Person* p = pqDesc.top(); std::cout << p->name << " - age: " << p->age << std::endl; pqDesc.pop(); delete p; // 记得手动释放指针内存! } // 测试升序队列 std::priority_queue<Person*, std::vector<Person*>, AgeAscendComp> pqAsc; pqAsc.push(new Person("Alice", 165, 25)); pqAsc.push(new Person("Bob", 180, 30)); pqAsc.push(new Person("Charlie", 175, 20)); std::cout << "\n升序输出(age小的优先):" << std::endl; while (!pqAsc.empty()) { Person* p = pqAsc.top(); std::cout << p->name << " - age: " << p->age << std::endl; pqAsc.pop(); delete p; } return 0; }
运行结果会是:
降序输出(age大的优先): Bob - age: 30 Alice - age: 25 Charlie - age: 20 升序输出(age小的优先): Charlie - age: 20 Alice - age: 25 Bob - age: 30
3. 额外提醒
- 因为你存的是裸指针,一定要记得用完后释放内存,避免泄漏;也可以换成
std::unique_ptr<Person>这类智能指针,不用手动管理内存。 - 比较器里要确保传入的指针不是空指针,否则访问
a->age会导致程序崩溃。
内容的提问来源于stack exchange,提问作者cenh
相关产品推荐
相关产品推荐

