C++11 priority_queue 优先队列的使用

向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;
}

猜你喜欢

转载自blog.csdn.net/niu91/article/details/109121528