C++中std::priority_queue的使用小结

 更新时间:2025年04月07日 08:37:03   作者:点云SLAM  
std::priority_queue是C++ STL提供的优先队列,本文主要介绍了C++中std::priority_queue的使用小结,具有一定的参考价值,感兴趣的可以了解一下

std::priority_queue 是 C++ STL 提供的 优先队列,它是一种 最大堆(默认情况下),可以用于高效地获取当前最大(或最小)的元素。

1. 基本用法

(1) 头文件

要使用 std::priority_queue,需要包含:

#include <queue>
#include <vector>
#include <iostream>

(2) 默认情况(最大堆)

默认情况下,std::priority_queue 是 最大堆,即 堆顶是最大元素:

std::priority_queue<int> pq;  // 默认是最大堆

示例:

#include <iostream>
#include <queue>

int main() {
    std::priority_queue<int> pq;

    pq.push(10);
    pq.push(30);
    pq.push(20);

    std::cout << "堆顶元素:" << pq.top() << std::endl;  // 输出 30

    pq.pop();  // 移除 30
    std::cout << "新的堆顶:" << pq.top() << std::endl;  // 输出 20

    return 0;
}

✅ 特点

  • push() 插入元素,自动维护最大堆。
  • top() 获取当前最大元素(堆顶)。
  • pop() 移除堆顶元素(但不返回它)。
  • size() 获取队列大小。
  • empty() 检查队列是否为空。

2. 自定义最小堆

如果要实现 最小堆(堆顶是最小元素),可以用 std::greater<T>

std::priority_queue<int, std::vector<int>, std::greater<int>> pq_min;

示例:

#include <iostream>
#include <queue>

int main() {
    std::priority_queue<int, std::vector<int>, std::greater<int>> pq_min;

    pq_min.push(10);
    pq_min.push(30);
    pq_min.push(20);

    std::cout << "堆顶元素:" << pq_min.top() << std::endl;  // 输出 10

    pq_min.pop();
    std::cout << "新的堆顶:" << pq_min.top() << std::endl;  // 输出 20

    return 0;
}

✅ 重点

  • std::greater<int> 使 priority_queue 变成 最小堆。

3. 自定义比较函数(结构体/仿函数)

(1) 结构体仿函数

struct Compare {
    bool operator()(int a, int b) {
        return a > b;  // 最小堆(a > b 表示 a 在 b 下面)
    }
};
std::priority_queue<int, std::vector<int>, Compare> pq;

示例:

#include <iostream>
#include <queue>

struct Compare {
    bool operator()(int a, int b) {
        return a > b;  // 让小的元素优先级高
    }
};

int main() {
    std::priority_queue<int, std::vector<int>, Compare> pq;

    pq.push(10);
    pq.push(30);
    pq.push(20);

    std::cout << "堆顶元素:" << pq.top() << std::endl;  // 输出 10

    pq.pop();
    std::cout << "新的堆顶:" << pq.top() << std::endl;  // 输出 20

    return 0;
}

✅ 优点

  • 适用于复杂的数据结构(如 struct)。
  • 允许灵活定义优先级。

4. 处理结构体类型

如果 priority_queue 存储的是 自定义结构体,需要提供比较规则。

(1) 按权重排序的任务调度

#include <iostream>
#include <queue>

struct Task {
    int id;
    int priority;

    // 重载运算符,用于最大堆(优先级大的优先)
    bool operator<(const Task& other) const {
        return priority < other.priority;  // 优先级高的排前面
    }
};

int main() {
    std::priority_queue<Task> pq;

    pq.push({1, 3});
    pq.push({2, 5});
    pq.push({3, 1});

    std::cout << "最高优先级任务 ID:" << pq.top().id << std::endl;  // 输出 2

    pq.pop();
    std::cout << "新的最高优先级任务 ID:" << pq.top().id << std::endl;  // 输出 1

    return 0;
}

✅ 特点

  • 默认是最大堆,因此 operator< 定义为 优先级小的在下面。

(2) 使用自定义比较函数

如果不能修改 struct,可以使用 外部比较函数:

struct CompareTask {
    bool operator()(const Task& a, const Task& b) {
        return a.priority > b.priority;  // 最小堆
    }
};

std::priority_queue<Task, std::vector<Task>, CompareTask> pq;

完整示例:

#include <iostream>
#include <queue>

struct Task {
    int id;
    int priority;
};

// 使 priority_queue 变成最小堆
struct CompareTask {
    bool operator()(const Task& a, const Task& b) {
        return a.priority > b.priority;  // 小优先级的任务优先
    }
};

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

    pq.push({1, 3});
    pq.push({2, 5});
    pq.push({3, 1});

    std::cout << "最高优先级任务 ID:" << pq.top().id << std::endl;  // 输出 3

    pq.pop();
    std::cout << "新的最高优先级任务 ID:" << pq.top().id << std::endl;  // 输出 1

    return 0;
}

✅ 适用场景

  • 优先队列调度算法
  • 事件驱动仿真
  • A 搜索(最短路径算法)*

5. priority_queue 适用场景

应用场景用法
最大堆(默认)std::priority_queue<int>
最小堆std::priority_queue<int, std::vector<int>, std::greater<int>>
存储结构体(最大堆)结构体重载 <
存储结构体(最小堆)std::greater<> 或自定义 Compare
K 大/小元素维护大小为 K 的堆
Dijkstra / A 搜索*结合 std::pair<int, int> 进行路径计算

6. 经典应用示例

(1) 找到前 K 个最大元素

#include <iostream>
#include <queue>
#include <vector>

void findTopK(std::vector<int>& nums, int k) {
    std::priority_queue<int, std::vector<int>, std::greater<int>> pq; // 最小堆

    for (int num : nums) {
        pq.push(num);
        if (pq.size() > k) pq.pop();  // 只保留 k 个最大值
    }

    std::cout << "前 " << k << " 个最大元素:" << pq.top() << std::endl;
}

int main() {
    std::vector<int> nums = {3, 1, 5, 12, 2, 11};
    findTopK(nums, 3);  // 输出 5
}

✅ 复杂度:O(N log K)

总结

  • std::priority_queue 默认是 最大堆,可以用 std::greater<> 实现 最小堆。
  • 存储结构体时,可以使用 重载 < 运算符 或 自定义比较器。
  • 适用于 任务调度、路径搜索(Dijkstra/A)等场景*。

到此这篇关于C++中std::priority_queue的使用小结的文章就介绍到这了,更多相关C++ std::priority_queue的使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • C++自定义函数判断某年某月某日是这一年中第几天

    C++自定义函数判断某年某月某日是这一年中第几天

    这篇文章主要介绍了C++自定义函数判断某年某月某日是这一年中第几天的方法,涉及C++日期与时间操作相关技巧,需要的朋友可以参考下
    2016-06-06
  • Qt项目打包的实现步骤

    Qt项目打包的实现步骤

    本文主要介绍了Qt项目打包的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • C++类的静态成员初始化详细讲解

    C++类的静态成员初始化详细讲解

    通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
    2013-09-09
  • C语言 sizeof 函数详情

    C语言 sizeof 函数详情

    这篇文章主要介绍了C语言 sizeof 函数,在 C 语言中,char 字符串也是一种非常重要的数据类型,我们除了使用 sizeof 函数获取字符串长度之外,使用 sizeof 函数同样也可以完成字符串长度的获取,下面文章内容具体描述该内容,需要的朋友可以参考以下
    2021-10-10
  • C语言限制链表最大长度的方法实现

    C语言限制链表最大长度的方法实现

    本文主要介绍了C语言中限制链表的长度,通过在添加新元素时检查链表的当前长度是否已经达到预设的最大值来实现,具有一定的参考价值,感兴趣的可以了解一下
    2025-03-03
  • C语言中怎么在main函数开始前执行函数

    C语言中怎么在main函数开始前执行函数

    C语言中怎么在main函数开始前执行函数呢?下面小编就大家详细的介绍一下。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-10-10
  • 浅谈c++性能测试工具google benchmark

    浅谈c++性能测试工具google benchmark

    本文将会介绍如何使用模板以及参数生成器来批量生成测试用例,简化繁琐的性能测试代码
    2021-06-06
  • C语言实现UDP通信

    C语言实现UDP通信

    这篇文章主要为大家详细介绍了C语言实现UDP通信,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • C语言三个函数的模拟实现详解

    C语言三个函数的模拟实现详解

    这篇文章主要为大家详细介绍了C语言三个函数的模拟实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • 浅析c#中WebBrowser控件的使用方法

    浅析c#中WebBrowser控件的使用方法

    以下是对c#中WebBrowser控件的使用方法进行了详细的分析介绍,需要的朋友参考下
    2013-07-07

最新评论