今天写leetcode时遇到一题,没思路,然后看了灵神的题解,其中的一个方法中的代码出现了,priority_queue这个容器,以前没遇到过就去搜索了一下相关的知识。
priority_queue
是 C++ 标准库中提供的一个容器适配器,它实现了一个优先队列数据结构。优先队列是一种特殊的队列,它的特点是队首元素始终是队列中优先级最高的元素。
它的一些重要特点:
- 首先,
priority_queue
使用了堆(通常是二叉堆)来实现,以保证队首元素是优先级最高的。 - 默认情况下,
priority_queue
是一个最大堆,也就是说队首元素是最大的元素。 - 可以通过自定义比较函数来改变元素的排序规则,从而实现最小堆或其他自定义的优先级队列。
还有一些函数:
push()
:将元素插入优先队列。pop()
:移除队首元素。top()
:访问队首元素。empty()
:检查优先队列是否为空。size()
:返回优先队列中元素的个数。
由于priority_queue的元素存储是基于堆的,所以priority_queue
不提供迭代器访问功能,因为其元素的存储是基于堆的,堆并不支持随机访问。并且修改 priority_queue
中的元素值是不被允许的,因为这会破坏堆的结构,破坏其优先级性质。
优先队列的定义:
priority_queue<Type, Container, Functional>
Type 是数据类型,Container 是容器类型(Container必须是用数组实现的容器,如vector,deque等等,但不能用 list。STL里面默认用的是vector),Functional 是比较方式,当需要用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大顶堆
//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> >q;
//greater和less是std中实现的两个仿函数
//仿函数又称为函数对象是一个能行使函数功能的类。
仿函数的语法几乎和我们普通的函数调用一样,不过作为仿函数的类,都必须重载 operator() 运算符。因为调用仿函数,实际上就是通过类对象调用重载后的 operator() 运算符。
总的来说,优先队列(Priority Queue)是一种特殊的队列数据结构,它的特点是队列中的元素按照一定的优先级顺序排列,而不是按照它们被插入的顺序排列。在优先队列中,队首元素是优先级最高的元素,也就是说它是队列中权值最小(或最大,具体取决于实现方式)的元素。
优先队列的主要特点包括:
-
有序性:优先队列中的元素按照一定的优先级顺序排列,通常使用堆(Heap)数据结构来实现,堆是一种完全二叉树,满足堆性质,即父节点的值(优先级)不大于(或不小于)其子节点的值。
-
插入和删除操作的复杂度:优先队列的插入和删除操作的时间复杂度通常为 O(log n),其中 n 是优先队列中的元素个数,这是由于堆的性质决定的。
-
元素访问:通常情况下,优先队列只支持访问队首元素,即访问优先级最高的元素,而不支持随机访问。
-
没有迭代器:优先队列通常不支持迭代器,因为堆的存储结构并不适合随机访问,但可以通过弹出元素的方式来访问队列中的元素。
在 C++ 中,优先队列通常使用 priority_queue
模板类来实现,它提供了一个简单的接口用于插入和删除元素,并且可以通过自定义比较函数来定义元素之间的优先级规则。