导读:本期聚焦于小伙伴创作的《C++ priority_queue怎么使用?优先队列自定义排序方法有哪些?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++ priority_queue怎么使用?优先队列自定义排序方法有哪些?》有用,将其分享出去将是对创作者最好的鼓励。

C++的priority_queue属于容器适配器,底层默认基于vector实现,遵循大顶堆的规则,队首元素始终是队列中优先级最高的元素,也就是默认情况下最大的元素。它在很多需要频繁获取最值的场景中非常实用,比如任务调度、TopK问题求解等。

C++ priority_queue怎么使用?优先队列自定义排序方法有哪些?

priority_queue基本用法

头文件与定义

使用priority_queue需要先包含头文件<queue>,默认的定义方式如下:

#include <queue>
#include <iostream>
using namespace std;

int main() {
    // 默认大顶堆,队首是最大的元素
    priority_queue<int> pq;
    return 0;
}

常用成员函数

priority_queue的常用操作比较少,主要包含以下几个:

  • push(const T& val):向优先队列中插入元素,插入后会自动调整堆结构保证队首是优先级最高的元素
  • pop():删除队首元素,删除后同样会调整堆结构
  • top():返回队首元素的引用,注意不会删除该元素
  • empty():判断队列是否为空,为空返回true,否则返回false
  • size():返回队列中元素的个数

下面是一个基本用法的示例:

#include <queue>
#include <iostream>
using namespace std;

int main() {
    priority_queue<int> pq;
    // 插入元素
    pq.push(3);
    pq.push(1);
    pq.push(5);
    pq.push(2);
    // 输出队首元素,此时应该是5
    cout << "队首元素:" << pq.top() << endl;
    // 删除队首元素
    pq.pop();
    // 再次输出队首元素,此时应该是3
    cout << "删除后队首元素:" << pq.top() << endl;
    // 遍历所有元素,注意优先队列不支持直接遍历,需要逐个弹出
    cout << "所有元素从大到小:" ;
    while (!pq.empty()) {
        cout << pq.top() << " ";
        pq.pop();
    }
    cout << endl;
    return 0;
}

priority_queue自定义排序方法

默认的priority_queue是大顶堆,如果我们想要小顶堆,或者按照自定义的规则排序,就需要传入自定义的比较方式,常见的有以下三种方法。

方法一:使用标准库提供的比较函数对象

对于基础数据类型,我们可以使用<functional>头文件中的greater<T>来实现小顶堆,定义时需要传入两个模板参数,第一个是元素类型,第二个是底层容器类型,第三个是比较规则。底层容器默认是vector,所以通常可以省略第二个参数,只传第三个参数。

#include <queue>
#include <functional>
#include <iostream>
using namespace std;

int main() {
    // 小顶堆,队首是最小的元素
    priority_queue<int, vector<int>, greater<int>> min_pq;
    min_pq.push(3);
    min_pq.push(1);
    min_pq.push(5);
    min_pq.push(2);
    cout << "小顶堆队首元素:" << min_pq.top() << endl; // 输出1
    return 0;
}

方法二:自定义比较结构体

当我们需要更复杂的排序规则时,可以自定义一个比较结构体,重载operator()函数,在函数内定义比较规则。注意priority_queue的比较规则和sort是相反的,sort中返回true表示第一个参数排在第二个前面,而priority_queue中返回true表示第一个参数的优先级比第二个低。

比如我们要定义一个存储学生信息的优先队列,按照学生的分数从高到低排序,分数相同按照年龄从小到大排序:

#include <queue>
#include <string>
#include <iostream>
using namespace std;

struct Student {
    string name;
    int score;
    int age;
};

// 自定义比较结构体
struct StudentCompare {
    bool operator()(const Student& a, const Student& b) const {
        // 分数高的优先级高,所以分数低的优先级低,返回true
        if (a.score != b.score) {
            return a.score < b.score;
        }
        // 分数相同,年龄小的优先级高,所以年龄大的优先级低,返回true
        return a.age > b.age;
    }
};

int main() {
    priority_queue<Student, vector<Student>, StudentCompare> stu_pq;
    stu_pq.push({"张三", 90, 20});
    stu_pq.push({"李四", 95, 19});
    stu_pq.push({"王五", 90, 18});
    // 输出队首学生,应该是李四,分数最高
    Student top_stu = stu_pq.top();
    cout << "最高分学生:" << top_stu.name << " 分数:" << top_stu.score << " 年龄:" << top_stu.age << endl;
    stu_pq.pop();
    // 接下来是张三和王五分数相同,王五年龄小,所以王五优先
    top_stu = stu_pq.top();
    cout << "第二高分学生:" << top_stu.name << " 分数:" << top_stu.score << " 年龄:" << top_stu.age << endl;
    return 0;
}

方法三:使用lambda表达式配合decltype

C++11之后我们还可以使用lambda表达式来定义比较规则,这时候需要注意定义priority_queue时需要传入lambda的类型,通常用decltype来获取,同时需要在构造函数中传入lambda表达式作为比较对象。

#include <queue>
#include <iostream>
#include <functional>
using namespace std;

int main() {
    // 定义lambda表达式,实现小顶堆
    auto cmp = [](int a, int b) {
        return a > b; // a比b大的时候,a的优先级比b低,所以是小顶堆
    };
    // 定义优先队列,模板参数需要decltype(cmp)
    priority_queue<int, vector<int>, decltype(cmp)> pq(cmp);
    pq.push(3);
    pq.push(1);
    pq.push(5);
    pq.push(2);
    cout << "小顶堆队首:" << pq.top() << endl; // 输出1
    return 0;
}

注意事项

  • priority_queue不支持随机访问,只能通过top()访问队首元素,没有迭代器,不能直接遍历所有元素
  • 自定义比较规则的时候要注意和sort的比较规则相反,避免逻辑错误
  • 如果存储的是自定义类型,需要保证比较规则中不会修改元素的值,最好将operator()定义为const成员函数
  • 插入和删除元素的时间复杂度都是O(log n),获取队首元素的时间复杂度是O(1),效率比较高

priority_queue优先队列自定义排序C++修改时间:2026-07-01 02:00:42

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。