优先队列(priority queue)是一种抽象数据类型,在解决最值类题目中经常用到,而且非常简便、好用。优先队列是一种特殊的队列,其中每个元素都有一个优先级,根据这个优先级对队内的元素进行排序,根据排序的顺序分为大根堆与小根堆,正因为有这种排列顺序,在一些算法题目解答非常方便。下面进行详细介绍优先队列(priority_queue)。
一、算法引入
假设有一个算法班级要根据算法考试成绩重新分配教室座位,7 人的算法成绩根据大根堆排列如下,那么此时学生排成的队列就属于优先队列,优先级最高的也就是分数最高的优先出队列选座位,依次进行直到队列为空为止。
我们假设新来了一位同学,他的算法成绩为 95 分,老师并不会因为他是后来的就把他放到队列最后面,而是根据他的算法成绩放到应该的位置。
二、什么是优先队列?
优先队列是一种特殊的队列数据结构,其中每个元素都有一个与之相关的优先级,元素的出队顺序不是按照进入队列的时间(queue),而是按照优先级决定的。可以理解为每入队一个元素,此元素就去队列里面找自己的优先级位置。
特点:
- 排序:元素按照优先级排序,优先级可以是自然顺序(如数字的升序)或自定义顺序。当优先级相同时,可以根据插入顺序(稳定性)或者平台定义的规则决定出队顺序
- 高效操作:插入和删除操作通常是高效的,尤其是在使用堆(Heap)作为底层数据结构时。
- 无序访问:通常不允许随机访问队列中的元素 (q[t],任意下标),只能访问队头的元素(q.top())。
前面我们说优先队列根据排序的顺序分为大根堆与小根堆,那么我们在建立优先队列时就分别可以建立两种优先队列,分别是底层基于大根堆实现的降序队列与底层基于小根堆实现的升序队列。定义优先队列需要包含头文件#include
#include<queue>//头文件 priority_queue<int> q1; q1 默认是大根堆也就是降序队列,一般写法只需要写一个类型 int、double 等 priority_queue<int,vector<int>,greater<int>> q2; q2 是小根堆也就是升序队列,三个参数必须写全,记住 greater 是升序队列 priority_queue<int,vector<int>,less<int>> q3; q3 是 q1 的具体写法,把三个参数都写上了,less 是降序队列,默认写法是 q1
三、常见操作
优先队列的基本操作包括以下几种:
1. 插入元素(q.push(t))
向优先队列中添加一个新元素 t,元素 t 根据优先级自动找好自己的位置。
- 时间复杂度:
O(log n)(基于堆的实现)。
q1.push(1); int n=2; q1.push(n);
2. 获取优先级最高/低的元素(q.top())
查看但不移除优先队列优先级最高/最低(大根堆/小根堆)的元素。
- 时间复杂度:
O(1)(基于堆的实现)。
q1.push(1); int n=2; q(n); q();


