目录
导读
我们上次学习了栈和队列,今天我们来学习优先队列,主要是了解它的一些基本使用和如何模拟实现。
一、什么是优先队列
优先队列(Priority Queue)是一种高效的数据结构,它是队列的一种扩展,不同之处在于每个元素都有一个相关的优先级。在优先队列中,元素不是按照插入的顺序进行排列,而是按照元素的优先级进行排列,优先级高的元素排在前面。
优先队列的定义可以有多种方式,其中一种常见的定义方式是基于堆(Heap)数据结构实现的。堆是一种二叉树,满足以下两个条件:
- 堆的根节点是最小或最大元素,即满足最小堆或最大堆的性质。
- 堆的每个节点的值都小于或大于其子节点的值,即满足堆的有序性。
基于堆实现的优先队列可以使用数组或链表来表示堆结构,并提供一些基本的操作,如插入元素、删除优先级最高的元素等。插入元素时,根据元素的优先级,将元素插入到合适的位置;删除元素时,取出优先级最高的元素,并保持堆的有序性。
不同于普通队列的FIFO(先进先出)特性,优先队列的元素按照优先级进行排序,具有最高优先级的元素会被最先处理。
特点:
-
元素具有优先级:与普通队列不同,优先队列中的元素具有优先级。每个元素都被赋予一个优先级值,用来确定其在队列中的位置。
-
按优先级排序:优先队列中的元素按照优先级进行排序。具有最高优先级的元素会被放在队列的最前面。
-
自动排序:在插入元素时,优先队列会自动根据元素的优先级进行排序。较高优先级的元素会被排在前面,较低优先级的元素会被排在后面。
-
快速访问最高优先级元素:优先队列支持快速访问具有最高优先级的元素。可以通过获取队列的顶部元素来获得具有最高优先级的元素。
-
插入和删除操作的时间复杂度:在堆实现的优先队列中,插入和删除元素的平均时间复杂度为O(log n),其中n是当前队列中的元素个数。
需要注意的是,优先队列并不保证相同优先级的元素的顺序,它只保证具有较高优先级的元素会被优先处理。如果需要保持相同优先级元素的顺序,可以通过自定义比较函数来实现。
二、优先队列的使用
1. 优先队列的构造
默认情况下,priority_queue使用less<int>作为比较器,以使元素按降序排列。也就是大堆。
如果要使用其他比较器或自定义排序规则,可以在创建优先队列对象时传递一个比较器函数对象或lambda表达式。
例如,要使元素按升序排列,可以使用以下代码:
priority_queue<int, vector<int>, greater<int>> pq;
优先队列的构造方式有以下几种:
-
默认构造:使用无参构造函数创建一个空的优先队列,例如:
priority_queue<int> pq; -
指定容器构造:可以通过指定容器类型和容器对象来构造优先队列。例如,使用
vector容器构造一个最大堆优先队列:priority_queue<int, vector<int>> pq;,使用现有的vector对象构造优先队列:vector<int> vec; priority_queue<int, vector<int>> pq(vec); -
指定比较函数构造:可以通过指定一个自定义的比较函数来构造优先队列,以改变默认的元素优先级比较规则。比较函数可以是自定义的函数、函数指针或者函数对象。例如,构造一个从小到大排序的优先队列:
priority_queue<int, vector<int>, greater<int>> pq;,构造一个使用自定义比较函数的优先队列:auto cmp = [](int a, int b){ return a % 10 < b % 10; }; priority_queue<int, vector<int>, decltype(cmp)> pq(cmp);
2. 优先队列的基本操作
优先队列的基本操作包括插入元素、删除最高优先级元素、判断队列是否为空等。常用的操作函数有:
push(element):将元素插入到优先队列中。pop():移除优先队列中的最高优先级元素。top():返回优先队列中的最高优先级元素。empty():判断优先队列是否为空,如果为空返回true,否则返回false。size():返回优先队列中元素的个数。
3. 使用示例
1. 包含头文件:首先需要包含<queue>头文件
#include <queue>
2. 定义优先队列:使用priority_queue类定义一个优先队列对象(默认大堆)

最低0.47元/天 解锁文章
9614

被折叠的 条评论
为什么被折叠?



