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本身的类型是无法显示写出的)

 

posted @ 2021-02-11 10:37  Kinghao0319  阅读(45)  评论(0)    收藏  举报