【STL】STL之priority_queue

用途

优先队列,保证每次的队首元素都是优先级最大的。可以用来解决一些贪心问题,也可以对 Dijkstra 算法进行优化(优先队列的本质是堆)。

头文件

# include <queue>

定义

priority_queue<Type, Container, Functional>

Type为数据类型, Container为保存数据的容器,Functional为元素比较方式。

如果不写后两个参数,那么容器默认用的是vector,比较方式默认用operator<,也就是优先队列是大根堆,队头元素最大。

容器内元素访问

与队列不同,优先队列只能通过 top() 函数来访问队首元素,见下方。

常用函数

  1. q.push(x): 将 x 入队。
  2. q.pop():将队首元素出队。
  3. q.top():获得队首元素。
  4. q.empty():检测队列是否为空,返回 true 则为空,返回 false 则非空。
  5. q.size():返回队列中元素的个数。

注意:使用 top() 和 pop() 函数前,应当先用 empty() 判断队列是否为空。

priority_queue 内元素优先级的设置

基本数据类型的优先级设置

priority_queue<int> q;
priority_queue<int, vector<int>, less<int>> q;

以上两句是等价的。第二句中,第二个参数 vector<int> 填写的是来承载底层数据结构堆的容器,如果第一个参数是 double 型就填写 vector<double>,第一个参数是 char 型就填写 vector<char>。第三个参数 less<int> 表示数字大的优先级大(默认情况)。若想让数字小的优先级大,则改为 greater<int>

priority_queue<int, vector<int>, greater<int> > q; //注意两个 > 之间需加空格
q.push(3);
q.push(4);
q.push(1);
printf("%d", q.top());

输出结果:

1

自定义数据类型的优先级设置

例如,对水果的名称和价格建立一个结构体,现在希望按水果的价格高的为优先级高,写法如下:

# include <stdio.h>
# include <vector>
# include <queue>
# include <string>
# include <iostream>

using namespace std;

// 方法1:
// 重载 < 操作符
// struct fruit
// {
//   string name;
//   int price;
//   friend bool operator < (const fruit &f1, const fruit &f2);
// };

// bool operator < (const fruit &f1, const fruit &f2){
//   return f1.price < f2.price;
// }

// 方法2:
// 自定义比较函数
struct fruit
{
  string name;
  int price;
};

struct cmp{
  bool operator() (const fruit &f1, const fruit &f2){
    return f1.price < f2.price;
  }
};


int main(){
  priority_queue<fruit, vector<fruit>, cmp> q;
  fruit f1, f2, f3;
  f1.name = "banana";
  f1.price = 3;
  f2.name = "peach";
  f2.price = 4;
  f3.name = "apple";
  f3.price = 1;
  q.push(f1);
  q.push(f2);
  q.push(f3);
  cout << q.top().name << " " << q.top().price << endl;
  system("pause");
  return 0;
}


输出:
在这里插入图片描述

两种比较方式:重载操作符 < 或者自定义比较函数。

注意: priority_queue默认是大根堆的方式,在自定义数据类型的优先级时,如果也想要大根堆,那么就正常地把比较函数写成小于的比较函数,如果想要小根堆,那就写成相反形式。如:

struct cmp{
  bool operator() (const fruit &f1, const fruit &f2){
    return f1.price > f2.price;
  }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值