STL priority_queue 常见用法详解
《算法笔记》学习笔记
priority_queue 常见用法详解
//priority_queue又称优先队列,其底层时用堆来实现的。
//在优先队列中,队首元素一定是当前队列中优先级最高的那一个。
桃子(优先级 3)
梨子(优先级 4)
苹果(优先级 1)
//那么出队顺序是:梨子(4) -> 桃子(3) -> 苹果(1)
//可以在任何时候往优先队列里面加入(push)元素,而优先队列底层的数据结构对(heap)
//会随时调整结构,使得每次的队首元素都是优先级最大的
1. priority_queue 的定义
//定义
priority_queue< typename > name;
2. priority_queue容器内元素访问
//只能通过top()函数来访问队首元素(也称堆顶元素),也就是优先级最高的元素
#include <stdio.h>
#include <queue>
using namespace std;
int main() {
priority_queue<int> q;
q.push(3);
q.push(4);
q.push(1);
printf("%d\n", q.top());
return 0;
}
3. priority_queue常用函数实例解析
(1) push()
//push(x)将令x入队,时间复杂度为O(logN),其中N为当前优先队列中的元素个数。
(2) top()
//top()可以获得队首元素,时间复杂度为O(1)
//使用top()函数之前,必须用empty()判断优先队列是否为空
(3) pop()
//pop()令队首元素出队,时间复杂度为O(logN),其中N为当前优先队列中的元素个数
#include <stdio.h>
#include <queue>
using namespace std;
int main() {
priority_queue<int> q;
q.push(3);
q.push(4);
q.push(5);
q.push(1);
printf("%d\n", q.top());
q.pop();
printf("%d\n", q.top());
return 0;
}
(4) empty()
//empty()检测优先队列是否为空,返回true则空,返回false则非空。时间复杂度为O(1)
#include <stdio.h>
#include <queue>
using namespace std;
int main() {
priority_queue<int> q;
if(q.empty() == true) { //一开始优先队列内没有元素,所以是空
printf("Empty\n");
} else {
printf("Not Empty\n");
}
q.push(1);
if(q.empty() == true) { //在加入"1"后,优先队列非空
printf("Empty\n");
} else {
printf("Not Empty\n");
}
return 0;
}
(5) size()
//size()返回优先队列内元素的个数,时间复杂度为O(1)
#include <stdio.h>
#include <queue>
using namespace std;
int main() {
priority_queue std;
q.push(3);
q.push(4);
q.push(1);
printf("%d\n", q.size()); //优先队列中有三个元素
return 0;
}
4.priority_queue内元素优先级的设置
(1) 基本数据类型的优先级设置
//基本数据类型就是int型, double型, char型等可以直接使用的数据类型
//优先队列对他们的优先级设置一般是数字大的优先级越高
//因此队首元素就是优先队列内元素最大的那个(如果是char型,则是字典序最大的)
//下面两种优先队列的定义是等价的(以int型为例,注意最后两个>之间有一个空格):
priority_queue<int> q;
priority_queue<int, vector<int>, less<int>> q;
//第二种定义方式的尖括号内多出两个参数:vector<int>, less<int>
//其中vector<int>填写的是来承载底层数据结构堆(heap)的容器
//如果第一个参数是double型或char型,则此处只需要填写vector<double>或vector<char
//第三个参数less<int>则是对第一个参数的比较类。
//less<int>表示数字大的优先级越大,而greater<int>表示数字小优先级越大
//优先队列总数把最小的元素放在队首,定义
priority_queue<int, vector<int>, greater<int>>q;
//示例
#include <stdio.h>
#include <queue>
using namespace std;
int main() {
priority_queue<int, vector<int>, greater<int>> q;
q.push(3);
q.push(4);
q.push(1);
printf("%d\n", q.top());
return 0;
}
(2) 结构体的优先级设置
//对水果的名称和价格建立结构体
struct fruit {
string name;
int price;
};
//现在希望水果的价格高的为优先级高,就需要重载(overload)小于"<"。
//重载是指对已有的运算符进行重新定义,也就是说,可以改变小于号的功能。
struct fruit {
string name;
int price;
friend bool oprator < (fruit f1, fruit f2) {
return f1.price < f2.price;
}
};
//fruit结构体种增加了一个函数,其中"friend"为友元。
//想要以价格低的水果为优先级高,只需要把return中的小于号改为大于号即可。
struct fruit {
string name;
int price;
friend bool operator < (fruit f1, fruit f2) {
return f1.price > f2.price;
}
};
//示例:
#include <iostream>
#include <string>
#include <queuen>
using namespace std;
struct fruit {
string name;
int price;
friend bool operator < (fruit f1, fruit f2) {
return f1.price > f2.price;
}
}f1, f2, f3;
int main() {
priority_queue<fruit> q;
f1.name = "桃子";
f1.price = 3;
f2.name = "梨子";
f2.price = 4;
f3.name = "苹果";
f3.price = 1;
q.push(f1);
q.push(f2);
q.push(f3);
cout << q.top().name << " " << q.top().price << endl;
return 0;
}
//优先队列的这个函数与sort中的cmp函数的效果是相反的
//上面的函数有没有办法同sort中的cmp函数那样卸载结构体外面
//方法:把friend去掉,把小于号改成一对小括号,然后把重载的函数写在结构体外面
//同时将其用struct包装起来
struct cmp {
bool operator () (fruit f1,fruit f2) {
return f1.price > f2.price;
}
}
//这种情况需要使用第二种定义方法来定义优先队列
priority_queue<fruit, vector<fruit>, cmp> q;
//把greater<>部分换成cmp
#include <iostream>
#include <string>
#include <queue>
using namespace std;
struct fruit {
string name;
int price;
} f1, f2, f3;
struct cmp {
bool operator () (fruit f1, fruit f2) {
return f1.price > f2.price;
}
};
int main() {
prority_queue<fruit, vector<fruit>, cmp> q;
f1.name = "桃子";
f1.price = 3;
f2.name = "梨子";
f2.price = 4;
f3.name = "苹果";
f3.price = 1;
q.push(f1);
q.push(f2);
q.push(f3);
cout << q.top().name << " " << q.top().price << endl;
return 0;
}
//即使是基本数据类型或者其他STL容器(例如set),也可以通过同样的方式来定义优先级
//建议使用引用来提高效率,在比较类的参数种需要加上"const" 和"&"
friend bool operator < (const fruit &f1, const fruit &f2) {
return f1.price > f2.price;
}
bool operator () (const fruit &f1, const fruit &f2) {
return f1.price > f2.price;
}
5. priority_queueu的常见用途
- 可以解决一些贪心问题
- 也可以对Dijkstra算法进行优化(因为优先队列的本质是堆)
STL priority_queue 常见用法详解的更多相关文章
- STL stack 常见用法详解
<算法笔记>学习笔记 stack 常见用法详解 stack翻译为栈,是STL中实现的一个后进先出的容器.' 1.stack的定义 //要使用stack,应先添加头文件#include &l ...
- STL queue 常见用法详解
<算法笔记>学习笔记 queue 常见用法详解 queue翻译为队列,在STL中主要则是实现了一个先进先出的容器. 1. queue 的定义 //要使用queue,应先添加头文件#incl ...
- STL map 常见用法详解
<算法笔记>学习笔记 map 常见用法详解 map翻译为映射,也是常用的STL容器 map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器) 1. map 的定义 / ...
- STL set 常见用法详解
<算法笔记>学习笔记 set 常见用法详解 set是一个内部自动有序且不含重复元素的容器 1. set 的定义 //单独定义一个set set<typename> name: ...
- STL vector常见用法详解
<算法笔记>中摘取 vector常见用法详解 1. vector的定义 vector<typename> name; //typename可以是任何基本类型,例如int, do ...
- STL pair 常见用法详解
<算法笔记>学习笔记 pair 常见用法详解 //pair是一个很实用的"小玩意",当想要将两个元素绑在一起作为一个合成元素, //又不想因此定义结构体时,使用pair ...
- STL string 常见用法详解
string 常见用法详解 1. string 的定义 //定义string的方式跟基本数据类型相同,只需要在string后跟上变量名即可 string str; //如果要初始化,可以直接给stri ...
- C++标准模板库(STL)——queue常见用法详解
queue的定义 queue<typename> name; queue容器内元素的访问 由于队列本身就是一种先进先出的限制性数据结构,因此在STL中只能通过front()来访问队首元素, ...
- C++标准模板库(STL)——set常见用法详解
set的定义 set<typename> name; typename可以是任何基本类型,如int.double.char.结构体等,也可以是STL标准容器,如vector.set.que ...
随机推荐
- 我理解的windows中断管理
只谈外部中断的windows内核管理,异常和trap不在此文的讨论之列. 1. windows中断总貌 在windows中,物理上的中断源被抽象为KINTERRUPT结构.一个中断源在windows中 ...
- Java的23种设计模式 <二>
1.单例模式(Singleton Pattern) 定义:Ensure a class has only one instance, and provide a global point of acc ...
- Java 面试题 二
1.线程怎么保持同步 关于线程同步(7种方式) --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3897440.html"谢谢 ...
- MySQL 5.7半同步复制技术
一.复制架构衍生史 在谈这个特性之前,我们先来看看MySQL的复制架构衍生史. 在2000年,MySQL 3.23.15版本引入了Replication.Replication作为一种准实时同步方式, ...
- 云闪付个人免签支付用xposed解决强制升级
云闪付的xposed程序之前用的是6.18的版本,前段时间突然不能用了,提示要升级到最新的7.0版本.之前这个云闪付的个人免签支付程序一直跑的挺好,云闪付也是所有免签支付里面最能跑量的,不甘就这么放弃 ...
- 【Redis 向Redis中批量导入mysql中的数据(亲自测试)】
转自:https://blog.csdn.net/kenianni/article/details/84910638 有改动,仅供个人学习 问题提出:缓存的冷启动问题 应用系统新版本上线,这时候 re ...
- DOM操作的性能优化
DOM操作的真正问题在于 每次操作都会出发布局的改变.DOM树的修改和渲染. React解决了大面积的DOM操作的性能问题,实现了一个虚拟DOM,即virtual DOM,这个我们一条条讲. 所以关于 ...
- axios的get请求无法设置Content-Type
最近在与后端的项目对接中,接口工具使用了axios这个东西.怎么说那 ,反正有很多坑,在后端的请求中要设置GET 请求中要设置header中的Content-Type为application/json ...
- 快速解决设置Android 23.0以上版本对SD卡的读写权限无效的问题
快速解决设置Android 23.0以上版本对SD卡的读写权限无效的问题 转 https://www.jb51.net/article/144939.htm 今天小编就为大家分享一篇快速解决设置And ...
- selenium死活定位不到元素以及radio单选框点击不生效
今天操作一个单选框浪费太多时间,现在其实很简单得东西,记录一下: 1,问题一,定位不到 如图,使用selenium IDE和xpath helper都试过,无法成功定位到这个单选框,实际上是因为,这个 ...