C++中的priority_queue容器使用及说明

 更新时间:2026年04月10日 08:51:01   作者:你的冰西瓜  
文章主要介绍了C++标准模板库中的优先级队列(priority_queue)的功能、实现原理、使用方法及应用场景,优先级队列提供按优先级排序的数据存储方式,默认为最大堆实现,通过分析其构造函数、操作函数、性能考虑等内容,展示了优先级队列在实际应用中的优势与注意事项

1.priority_queue概述

priority_queue是C++标准模板库(STL)中的容器适配器,提供优先级队列功能。它保证优先级最高的元素总是位于队列前端,默认情况下是最大堆实现(最大元素优先)。

2. 基本特性

  • 优先级排序:元素按优先级排序,默认最大元素在前
  • 容器适配器:基于其他序列容器实现(默认vector
  • 限制访问:只允许访问顶部元素
  • 高效操作:插入和删除操作时间复杂度为O(log⁡2n)O(\log_2 n)O(log2n)
  • 堆结构:底层使用堆数据结构实现

3. 头文件与声明

#include <queue>  // 注意:priority_queue也在<queue>头文件中
using namespace std;

priority_queue<int> pq1;  // 默认最大堆,基于vector
priority_queue<int, vector<int>, greater<int>> pq2;  // 最小堆
priority_queue<string> pq3;

4. 构造函数与初始化

4.1 默认构造

priority_queue<int> pq;  // 创建空的最大堆

4.2 基于比较函数构造

// 自定义比较函数
struct Compare {
    bool operator()(int a, int b) {
        return a > b;  // 最小堆
    }
};
priority_queue<int, vector<int>, Compare> custom_pq;

4.3 使用已有数据初始化

vector<int> vec = {3, 1, 4, 1, 5};
priority_queue<int> pq(vec.begin(), vec.end());  // 使用迭代器范围构造

5. 容量操作

5.1empty()

if (pq.empty()) {
    cout << "优先级队列为空";
}

5.2size()

cout << "优先级队列大小: " << pq.size();

6. 元素访问

6.1top()

if (!pq.empty()) {
    cout << "最高优先级元素: " << pq.top();
}

7. 修改操作

7.1push()

pq.push(10);  // 插入元素
pq.push(20);
pq.push(5);

7.2emplace()

pq.emplace(15);  // 原地构造元素(避免拷贝)

7.3pop()

if (!pq.empty()) {
    pq.pop();  // 移除最高优先级元素
}

7.4swap()(C++11)

priority_queue<int> pq2;
pq.swap(pq2);  // 交换两个优先级队列

8. 完整示例

#include <iostream>
#include <queue>
#include <vector>
#include <functional>  // 用于greater<int>
using namespace std;

int main() {
    // 最大堆示例
    priority_queue<int> max_heap;
    max_heap.push(30);
    max_heap.push(10);
    max_heap.push(50);
    max_heap.emplace(20);
    
    cout << "最大堆元素: ";
    while (!max_heap.empty()) {
        cout << max_heap.top() << " ";
        max_heap.pop();
    }
    cout << endl;
    
    // 最小堆示例
    priority_queue<int, vector<int>, greater<int>> min_heap;
    min_heap.push(30);
    min_heap.push(10);
    min_heap.push(50);
    min_heap.emplace(20);
    
    cout << "最小堆元素: ";
    while (!min_heap.empty()) {
        cout << min_heap.top() << " ";
        min_heap.pop();
    }
    cout << endl;
    
    // 自定义比较函数示例
    struct Point {
        int x, y;
        Point(int x, int y) : x(x), y(y) {}
        bool operator<(const Point& other) const {
            return (x*x + y*y) < (other.x*other.x + other.y*other.y);
        }
    };
    
    priority_queue<Point> point_pq;
    point_pq.emplace(1, 2);
    point_pq.emplace(3, 4);
    point_pq.emplace(0, 1);
    
    cout << "按与原点的距离排序的点: ";
    while (!point_pq.empty()) {
        Point p = point_pq.top();
        cout << "(" << p.x << "," << p.y << ") ";
        point_pq.pop();
    }
    cout << endl;
    
    return 0;
}

9. 底层容器与比较函数

9.1 底层容器选择

priority_queue可以基于以下容器实现:

  • vector(默认):随机访问性能好,适合堆操作
  • deque:两端操作高效,但内存使用不如vector紧凑

9.2 比较函数

  • less<T>(默认):最大堆,大元素优先
  • greater<T>:最小堆,小元素优先
  • 自定义比较函数:实现复杂排序逻辑
// 自定义比较函数示例:按字符串长度排序
struct LengthCompare {
    bool operator()(const string& a, const string& b) {
        return a.length() < b.length();  // 长度大的优先
    }
};
priority_queue<string, vector<string>, LengthCompare> length_pq;

10. 实际应用示例

10.1 合并KKK个有序链表

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};

struct CompareNode {
    bool operator()(ListNode* a, ListNode* b) {
        return a->val > b->val;  // 最小堆
    }
};

ListNode* mergeKLists(vector<ListNode*>& lists) {
    priority_queue<ListNode*, vector<ListNode*>, CompareNode> pq;
    
    for (auto node : lists) {
        if (node) pq.push(node);
    }
    
    ListNode dummy(0);
    ListNode* tail = &dummy;
    
    while (!pq.empty()) {
        tail->next = pq.top();
        pq.pop();
        tail = tail->next;
        
        if (tail->next) {
            pq.push(tail->next);
        }
    }
    
    return dummy.next;
}

10.2 查找前KKK个高频元素

vector<int> topKFrequent(vector<int>& nums, int k) {
    unordered_map<int, int> freq;
    for (int num : nums) freq[num]++;
    
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    
    for (auto& [num, count] : freq) {
        pq.push({count, num});
        if (pq.size() > k) {
            pq.pop();
        }
    }
    
    vector<int> result;
    while (!pq.empty()) {
        result.push_back(pq.top().second);
        pq.pop();
    }
    
    return result;
}

11. 性能考虑

时间复杂度

  • push(): O(log⁡2n)O(\log_2 n)O(log2n)
  • pop(): O(log⁡2n)O(\log_2 n)O(log2n)
  • top(): O(1)O(1)O(1)
  • empty(): O(1)O(1)O(1)
  • size(): O(1)O(1)O(1)

空间复杂度O(n)O(n)O(n)

底层容器选择影响

  • vector:内存局部性好,通常性能更优
  • deque:在某些情况下可能提供更好的性能

12. 注意事项

  1. 调用top()pop()前必须检查队列是否为空
  2. priority_queue不提供迭代器,无法遍历内部元素
  3. 自定义比较函数需要严格弱序
  4. 默认是最大堆,要创建最小堆需要显式指定greater<T>

13. priority_queue与其他容器比较

特性priority_queuequeueset
排序方式按优先级FIFO按键值排序
访问方式仅顶部元素队首和队尾任意元素
插入复杂度O(log⁡2n)O(\log_2 n)O(log2​n)O(1)O(1)O(1)O(log⁡2n)O(\log_2 n)O(log2​n)
删除复杂度O(log⁡2n)O(\log_2 n)O(log2​n)O(1)O(1)O(1)O(log⁡2n)O(\log_2 n)O(log2​n)
重复元素允许允许不允许

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C++实现简单职工信息管理系统

    C++实现简单职工信息管理系统

    本文给大家分享的是使用C++实现简单的职工信息管理系统的代码,本系统采用了面向对象的程序设计方法,所有的方法均以类为基础,感兴趣的小伙伴们可以参考一下
    2015-08-08
  • Visual Studio 2022 编译C++20代码的图文步骤

    Visual Studio 2022 编译C++20代码的图文步骤

    在Visual Studio中启用C++20 import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标准库模块,完成后通过Ctrl+F5编译含import的代码,下面就来介绍一下
    2025-06-06
  • C++实现简单通讯录系统

    C++实现简单通讯录系统

    这篇文章主要为大家详细介绍了C++实现简单通讯录系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • Qt Qml实现毛玻璃效果

    Qt Qml实现毛玻璃效果

    毛玻璃效果是一种常见的 UI 设计风格,它通过模糊背景并添加透明度和噪声效果,使界面元素看起来像是半透明的磨砂玻璃,下面我们来看看如何使用Qml实现毛玻璃效果吧
    2025-01-01
  • C++ Qt开发之ComboBox下拉组合框组件用法详解

    C++ Qt开发之ComboBox下拉组合框组件用法详解

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中,ComboBox(组合框)是一种常用的用户界面控件,它提供了一个下拉列表,允许用户从预定义的选项中选择一个,本文给大家介绍QComboBox类的一些常用方法,需要的朋友可以参考下
    2023-12-12
  • C语言 二级指针详解及示例代码

    C语言 二级指针详解及示例代码

    本文主要介绍C语言 二级指针,这里整理了C语言中二级指针的基础资料并附有示例代码和实现结果,帮助大家学习理解相关知识,有学习的朋友可以参考下
    2016-08-08
  • C++  线程(串行 并行 同步 异步)详解

    C++ 线程(串行 并行 同步 异步)详解

    这篇文章主要介绍了C++ 线程(串行 并行 同步 异步)详解的相关资料,需要的朋友可以参考下
    2017-07-07
  • 解析四方定理的应用

    解析四方定理的应用

    所有自然数至多只要用四个数的平方和就可以表示
    2013-05-05
  • C/C++获取Windows平台CPU占用率的方法

    C/C++获取Windows平台CPU占用率的方法

    最近在做系统信息相关的接口,为了实现跨平台,故在linux和Windows平台获取占用率信息,文章主要介绍Windows下的方法,文中给出了参考代码,需要的朋友可以参考下
    2023-12-12
  • matlab GUI指纹识别门禁系统介绍及源码实现

    matlab GUI指纹识别门禁系统介绍及源码实现

    这篇文章主要为大家介绍了matlab GUI指纹识别门禁系统的介绍及源码实现,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-02-02

最新评论