C++ priority_queue
1. 优先级队列,即堆,定义为priority_queue<Type, Container, Functional>
Type 就是数据类型,Container 就是容器类型,Functional是比较方式
//小顶堆 priority_queue <int,vector<int>,greater<int> > q; //大顶堆,不写比较默认是大顶堆 priority_queue <int,vector<int>,less<int> >q;
基本操作:
- top 访问队头元素
- empty 队列是否为空
- size 返回队列内元素个数
- push 插入元素到队尾 (并排序)
- emplace 原地构造一个元素并插入队列
- pop 弹出队头元素
- swap 交换内容
2. 自定义类型的比较
//自定义类型 struct myclass{ double pass; double total; myclass(int p,int t){//构造函数 pass=p; total=t; } }; //重载<运算符,实现比较 bool operator <(myclass a,myclass b){//返回true,a的优先级低 double ra=(a.total-a.pass)/((a.total+1)*a.total); double rb=(b.total-b.pass)/((b.total+1)*b.total); return ra<rb; } //使用时直接写类型就行了,默认的 vector 基础容器以及 less 排序规则 priority_queue<myclass> pq;
原理:通过重载 < 运算符,使得 std::less<T> 变得适用了
或者重载函数调用运算符
struct MyCompare { bool operator()(int a, int b) { return a > b; } // 小顶 }; // 直接使用类型名MyCompare,无需decltype std::priority_queue<int, std::vector<int>, MyCompare> pq;
3. 自定义比较函数,作为参数传入pq,要传参
auto cmp = [](int a, int b) { return a > b; }; // 小顶 // lambda的类型是编译器生成的匿名类型,必须用decltype推导 std::priority_queue<int, std::vector<int>, decltype(cmp)> pq(cmp); function<bool(pii,pii)> cmp = [](pii a,pii b) -> bool { double aa = (double)(a.second-a.first)/((double)a.second*(a.second+1)); double bb = (double)(b.second-b.first)/((double)b.second*(b.second+1)); return aa<bb; // max heap }; priority_queue<pii,vector<pii>, function<bool(pii,pii)>> pq(cmp);
这里的第三个模板参数类型,用lambda或者std::function都行(但lambda不直接等价于function,只是function可以封装lambda,lambda本身的类型是无法显示写出的)