向STL这种容器,我们可以先参考一下手册
http://www.cplusplus.com/reference/queue/priority_queue/?kw=priority_queue
使用场景
比如TopN问题
有一个任务集合,元素中包含任务信息和添加任务的时间戳。
当任务数量达到一定上限时,删除时间最长的任务。
那么如何找出时间最长的N个任务就可以用优先队列来解决。
常用操作
- top 访问队头元素
- empty 队列是否为空
- size 返回队列内元素个数
- push 插入元素到队尾 (并排序)
- pop 弹出队头元素
- emplace 原地构造一个元素并插入队列(C++11)
- swap 交换内容(C++11)
priority_queue 的内部结构可以看做是一个堆
This context is similar to a heap, where elements can be inserted at any moment, and only the max heap element can be retrieved (the one at the top in the priority queue).
它只能访问队列顶部的元素,也就是说只能通过top来获取元素,不支持随机访问或者说下标访问。
下面举一个例子, 插入d0-d5个任务到集合中,然后取前N个元素入优先队列,并输出
// g++ -std=c++11 ./demo2.cpp -o demo2
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <thread>
#include <unordered_map>
#include <unordered_set>
using namespace std;
typedef struct TASK_DATA //运算符重载<
{
std::string task_name;
int tim;
TASK_DATA(string i, int t) : task_name(i), tim(t) {
}
bool operator<(const TASK_DATA& a) const {
return tim < a.tim; }
} TASK_DATA;
bool operator==(const struct TASK_DATA& X, const struct TASK_DATA& Y) {
return Y.task_name == X.task_name;
}
struct DATA_hash {
size_t operator()(const struct TASK_DATA& _r) const {
return std::hash<string>()(_r.task_name);
}
};
int main() {
TASK_DATA d0("100", 101);
TASK_DATA d1("900", 102);
TASK_DATA d2("800", 103);
TASK_DATA d3("700", 100);
TASK_DATA d4("333", 105);
TASK_DATA d5("555", 106);
std::unordered_set<TASK_DATA, DATA_hash> sets;
sets.insert(d0);
sets.insert(d1);
sets.insert(d2);
sets.insert(d3);
sets.insert(d4);
sets.insert(d5);
std::cout << "unordered_set---" << std::endl;
for (auto& s : sets) {
std::cout << s.task_name << "--" << s.tim << std::endl;
}
TASK_DATA d6("555", 888);
auto s = sets.find(d6);
if (s != sets.end()) {
std::cout << "find it" << std::endl;
}
// 优先队列
priority_queue<TASK_DATA> task_queue;
// 取top N个元素
int N = 3;
for (auto& s : sets) {
if (task_queue.size() < N) {
task_queue.push(s);
} else {
auto b = task_queue.top();
if (s < b) {
task_queue.pop();
task_queue.push(s);
}
}
}
// 遍历
while (!task_queue.empty()) {
auto b = task_queue.top();
cout << b.task_name << "--" << b.tim << '\n';
task_queue.pop();
}
return 0;
}