当前位置: 首页 > news >正文

C++学习笔记(三十二)——priority_queue

一、 std::priority_queue

std::priority_queue 是 C++的STL 提供的优先级队列(Priority Queue),本质上是基于堆(Heap)实现的一个容器适配器

特点:

  • 默认是最大堆(Max Heap)top() 返回最大元素
  • 可以转换为最小堆(Min Heap)自定义比较方式
  • 插入 (push) 和删除 (pop) 复杂度为 O(log n)
  • 访问最大/最小值 (top) 复杂度为 O(1)

适用场景:

  • 求前 K 个最大/最小元素:使用最小堆(Min Heap)
  • 任务调度事件处理:使用 priority_queue 管理优先级
  • 如果存储复杂对象并求最大或最小:推荐使用 struct + operator<自定义比较类

二、priority_queue 的常用函数

函数作用
push(value)插入一个元素
pop()移除堆顶元素
top()返回堆顶元素
size()返回元素个数
empty()判断队列是否为空

三、priority_queue 的基本使用

(1) 默认最大堆(Max Heap)

作用:
std::priority_queue 默认是最大堆,即 top() 始终返回最大值

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

int main() {
    priority_queue<int> pq;  // 默认最大堆
    pq.push(10);
    pq.push(5);
    pq.push(20);
    pq.push(15);

    cout << "Priority Queue (Max Heap): ";
    while (!pq.empty()) {
        cout << pq.top() << " ";  // 输出最大元素
        pq.pop();  // 移除最大元素
    }
    cout << endl;

    system("pause");
    return 0;
}

注意:

  • push(10) → {10}
  • push(5) → {10, 5}
  • push(20) → {20, 5, 10}(自动维护最大堆)
  • push(15) → {20, 15, 10, 5}
  • pop() 依次取出 20 → 15 → 10 → 5

第三次插入元素时(pq.push(20);):

push
10
5
20

将元素20与其父节点元素10比较大小,互换位置
维护每个节点的键值都大于或等于其子节点键值的规则:

20
5
10

(2) 最小堆(Min Heap)

作用:
默认情况下 priority_queue最大堆,但可以用 std::greater<int> 创建最小堆(即 top() 返回最小元素)。

示例:

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

int main() {
    priority_queue<int, vector<int>, greater<int>> minHeap;  // 最小堆
    minHeap.push(10);
    minHeap.push(5);
    minHeap.push(20);
    minHeap.push(15);

    cout << "Priority Queue (Min Heap): ";
    while (!minHeap.empty())
    {
        cout << minHeap.top() << " ";
        minHeap.pop();
    }
    cout << endl;

    system("pause");
    return 0;
}

注意:

std::priority_queue<Type, std::vector<Type>, std::greater<Type>>
  • Type:数据类型(如 int)。
  • std::vector<Type>:底层容器(必须std::vector)。
  • std::greater<Type>:比较函数(默 std::less<Type> 代表最大堆)。

四、priority_queue 的应用

(1) 自定义 struct 比较

作用:
如果 priority_queue 需要存储复杂对象,如 struct,就需要自定义比较函数

示例:

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

struct Task {
    int priority;
    string name;

    // 自定义比较运算符,优先级高的排在前面
    bool operator<(const Task& other) const 
    {
        return priority < other.priority;  // 默认最大堆
    }
};

int main() {
    priority_queue<Task> pq;

    pq.push({ 3, "Low priority" });
    pq.push({ 5, "Medium priority" });
    pq.push({ 10, "High priority" });

    while (!pq.empty())
    {
        cout << pq.top().name << endl;
        pq.pop();
    }

    system("pause");
    return 0;
}

分析:

  • 任务 priority=10 最高,先出队。
  • 任务 priority=5 其次,再出队。
  • 任务 priority=3 最后出队。

(2) 使用 struct + 自定义 Compare 函数

作用:
如果需要最小堆(或者复杂排序规则),可以使用自定义比较类

示例:

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

struct Task {
    int priority;
    string name;
};

// 自定义比较函数(升序)
struct CompareTask 
{
    bool operator()(const Task& a, const Task& b) 
    {
        return a.priority > b.priority;  // 最小堆
    }
};

int main() {
    priority_queue<Task, vector<Task>, CompareTask> pq;

    pq.push({ 3, "Low priority" });
    pq.push({ 5, "Medium priority" });
    pq.push({ 10, "High priority" });

    while (!pq.empty())
    {
        cout << pq.top().name << endl;
        pq.pop();
    }

    system("pause");
    return 0;
}

注意:

  • CompareTaskpriority 小的优先级高,变成最小堆

(3) Top K 问题(求前 K 个最大元素)

示例:

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

vector<int> topKElements(vector<int>& nums, int k)
{
    priority_queue<int, vector<int>, greater<int>> minHeap;
    for (int num : nums) // 创建最小堆,插入元素
    {
        minHeap.push(num);
        if (minHeap.size() > k) // 若元素数大于K,则弹出最小值,保留前K个最大元素
            minHeap.pop();
    }

    vector<int> result;
    while (!minHeap.empty()) // 保存前K个最大元素
    {
        result.push_back(minHeap.top());
        minHeap.pop();
    }
    return result;
}

int main() {
    vector<int> nums = {10, 5, 20, 8, 25, 15};
    int k = 3;

    vector<int> result = topKElements(nums, k);
    for (int num : result)
    {
        cout << num << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

注意:

  • 维护一个大小为 k=3 的最小堆minHeap,确保存储最大的 k 个数

相关文章:

  • Java基础 4.1
  • OpenLayers:海量图形渲染之矢量切片
  • 07-01-自考数据结构(20331)- 排序-内部排序知识点
  • 【14】Selenium的基本使用
  • 一道积分_4
  • DJI上云API使用与配置
  • spring打包,打包错误
  • 供应链管理-经济指数:GDP、GNP、NNP、NDP、PPI、CPI、DPI...
  • WordPress汉主题
  • 二、基本应用工具
  • 云原生周刊:Kubernetes v1.33 要来了
  • 针对单台浪潮服务器运行Windows Server 2019和SQL Server的MES系统场景、高效能监控策略(兼顾软硬件健康)
  • golang 的channel
  • 函数类型声明
  • 大模型-提示词(Prompt)技巧
  • 大模型AI Agent的工作原理与安全挑战
  • Android 中集成 Google 应用内评分
  • JavaRedis和数据库相关面试题
  • Axure疑难杂症:完美解决中继器数据互通、增删改查(玩转中继器)
  • 在 Windows 环境下使用 VSCode 和 TinyGo 开发 ESP8266(NodeMcu) or STM32
  • 爱德华多·阿拉纳宣誓就任秘鲁新总理
  • 多条跨境铁路加速推进,谁是下一个“超级枢纽”?
  • 学习教育期间违规吃喝,李献林、叶金广等人被通报
  • 长三角议事厅·周报|从模速空间看上海街区化AI孵化模式
  • 世贸组织欢迎中美经贸高层会谈取得积极成果
  • 贵州省总工会党组成员、副主席梁伟接受审查调查