priority_queue容器概述
priority_queue是优先级队列,所以其也是队列的结构(队尾插入元素,队首获取和删除元素),之所以称之为优先级队列,是其不再像普通队列一样先进先出了,而是优先级高的先出队。
priority_queue的实现
priority_queue是一个模板类:
template <class _Ty, class _Container = vector<_Ty>, class _Pr = less<typename _Container::value_type>> class priority_queue {}
上面就是其模板的类型参数,其接收三个参数: 一个存储的数据类型,一个是存储数据的基础容器,一个是数据的排序规则(也就是优先级)。
priority_queue的基础容器
priority_queue和queue类似,也是依靠其内部的基础容器来存储数据的,在默认情况下(我们不指定)是以vector容器作为基础容器。
但是,我们也可以自己指定基础容器,但是只能使用vector和deque作为其基础容器。
为什么要传入排序规则呢?
因为,priority_queue是优先级队列,根据数据的优先级来决定谁先出队。
而我们的排序规则就是用来指定数据优先级的。比如: 指定数据从小到大排列,那么数据值越大优先级越高,数据越大越优先出队。
指定数据从大到小排列,那么数据值越小优先级越高,数据越小越优先出队。
关于第三个参数,我们可以使用函数对象来指定排序规则(或者说优先级规则),可以使用自定义的函数对象,也可以使用库中提供的函数对象(less和greater)。
在默认情况下(我们不指定的时候),其是以less(从小到大)作为其优先级规则的。
priority_queue中的函数
成员函数 | 功能 |
---|---|
empty() | 如果 priority_queue 为空的话,返回 true;反之,返回 false。 |
size() | 返回 priority_queue 中存储元素的个数。 |
top() | 返回 priority_queue 中第一个元素的引用形式。 |
push(const T& obj) | 根据既定的排序规则,将元素 obj 的副本存储到 priority_queue 中适当的位置。 |
push(T&& obj) | 根据既定的排序规则,将元素 obj 移动存储到 priority_queue 中适当的位置。 |
emplace(Args&&... args) | Args&&... args 表示构造一个存储类型的元素所需要的数据(对于类对象来说,可能需要多个数据构造出一个对象)。此函数的功能是根据既定的排序规则,在容器适配器适当的位置直接生成该新元素。 |
pop() | 移除 priority_queue 容器适配器中第一个元素。 |
swap(priority_queue<T>& other) | 将两个 priority_queue 容器适配器中的元素进行互换,需要注意的是,进行互换的 2 个 priority_queue 容器 |
priority_queue容器的基础容器只能使用vector,deque容器作为基础容器,不能使用list容器,默认情况下为vector容器,使用默认的容器可能会效率更高。
1. 创建priority_queue对象
使用默认构造函数创建
priority_queue<int> p1; // 创建一个存储int类型的对象p1,默认以vector作为其基础容器,和以less为函数对象指定优先级规则。
指定priority_queue的基础容器和优先级规则
基础容器:
我们可以通过类型参数的第二个参数指定priority_queue的基础容器,但是只能使用vector,deque这两个容器中的一个。
priority_queue<int,deque<int>> p1; // 创建p1,我们指定了deque容器作为priority_queue容器的基础容器。
注意: 除去默认情况(使用vector容器为默认情况),我们要使用其它容器作为priority_queue容器的基础容器,需要导入对应容器的头文件。还有,虽然我们可以指定基础容器,但是默认的基础容器的效率是最高的。
比如: 使用list为基础容器,需要导入list头文件#include <deque>
#inlcude <queue>
priority_queue<int,deque<int>> p1;
优先级规则:
我们可以通过第三个类型参数来指定priority_queue的优先级规则。比如: priority_queue<int,deque<int>,greater<int>> p1; // 定义一个priority_queue对象p1,指定其内部的优先级规则为greater函数对象指定。 -- 当然也可以自定义的函数对象指定。
使用数组的数据初始化priority_queue对象
int arr[] = { 1,2,3,5,4 };
priority_queue<int> p1(arr,arr+5);
上面我们创建一个priority_queue对象p1,默认以less作为优先级规则,我们使用arr数组中的元素对对象进行初始化,并且数组中的元素不需要是有序的,在数据添加到priority_queue对象中是,其会根据排序规则对数据进行排序。数组中的元素类型必须和priority_queue的存储类型一致。
使用别的容器的数据初始化priority_queue对象
vector<int> v1{ 10,1,3,5,2 };
priority_queue<int> p1(v1.begin(),v1.end());
上面我们创建一个priority_queue对象p1,和一个vector对象v1,我们使用v1和迭代器,使用v1中的数据对priority_queue进行初始化。
priority_queue<int> p1(less<int>(),v1);上面我们创建p1对象,接收两个参数一个是函数对象类的对象(用于指定排序规则),一个是另外一个容器的对象。
使用另外一个priority_queue对象初始化
vector<int> v1{ 10,1,3,5,2 };
priority_queue<int> p1(v1.begin(), v1.end());priority_queue<int> p2(p1);
上面代码,使用p1中的数据初始化p2中的数据。
priority_queue中的函数
- top() -- 无需参数
用于获取队首的元素,函数内部其实是调用了基础容器的front()函数。
队列只能从队首获取数据,要想获取别的数据就要先将前面的数据出队,然后才能从队首访问到。
- 其余函数
其余函数和上面函数是一样的,都是通过调用内部基础容器的相应函数来实现功能,但是其用法和基础容器对应函数的用法是一样的,所以就不再说明了。
priority_queue没有迭代器
priority_queue和queue类似,都没有迭代器,具体原因可以查看queue。