c++的STL(9)-- priority_queue

时间:2024-04-09 11:53:03

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中的函数 

表 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。