写在前面:大家好!我是【AI 菌】,一枚爱弹吉他的程序员。我
热爱AI、热爱分享、热爱开源
! 这博客是我对学习的一点总结与思考。如果您也对深度学习、机器视觉、算法、C++、Python
感兴趣,可以关注我的动态,我们一起学习,一起进步~
我的博客地址为:【AI 菌】的博客
上一篇:【C++养成计划】数据结构——栈stack(Day12)
昨天,我们了解了后进先出的栈,快速入门了stack类的用法。今天,我们来学习与之对应的一个数据结构——先进先出的队列,并且快速掌握STL queue类的使用方法!
1. 什么是队列?
说起队列,可能首先联想到的是食堂排得长长的队列。
那么编程语言中的队列又是怎么样的呢?
其实也是类似的,可以将队列视为一系列在排队等待打饭的汪星人,那么先加入这个队列的dog就会先得到食物离开;而后加入的dog不能插队,只能从队尾开始排队。
说到这里,其实大家已经对队列有了基本的了解了!
简单来说,队列就是一个FIFO(先进先出)的系统。元素只能从队尾插入,且最先插入的元素最先被删除。
2. STL queue类的使用
在实际问题中,只知道队列的含义是不够的,我们还需要在coding中去使用它。值得高兴的是,在C++中,已经提供了用于队列操作的queue类,这给我们使用队列提供了很大的方便,那么下面我们就赶紧上手queue类吧!
STL queue 是一个模板类,它只允许在末尾插入元素,并且从开头删除元素。在使用之前,必须包含头文件:
# include <queue>
(1) 实例化queue
std::queue定义如下所示:
template<
class elementType,
class Container = deque<Type>
>class queue;
解释:
1. elementType 是queue对象包含元素的类型
2. Container 是std::queue用于存储元素的集合类型,默认是deque,也可将该参数设置为list、vector。
当我们要使用queue类进行队列操作时,首先就要对其进行实例化。
下面演示了几种不同的实例化方法:
#include <iostream>
#include <queue>
#include <list>
using namespace std;
int main()
{
//1. 实例化一个整型队列nums,用来存放int类型元素
queue<int> nums;
//2. 实例化一个浮点型队列doubleNums
queue<double> doubleNums;
//3. 创建一个队列,元素类型为double,并使用list存储这些元素
queue<double, list<double>> doubleList;
//4. 使用一个queue(nums)去实例化另一个queue(numsCopy)
queue<int> numsCopy(nums);
return 0;
}
(2) queue的成员函数
由于我们的最终目的是,灵活地操作和处理队列。所以仅仅通过实例化创建queue是不够的,还需要学习queue的成员函数,从而更方便的处理队列问题。
下表列出了常用的queue的成员函数:
成员函数 | 功能 |
---|---|
push | 在队列尾新添一个元素 |
pop | 将队首的第一个元素删除 |
front | 返回指向队首元素的引用 |
back | 返回指向队尾元素的引用 |
empty | 检查队列是否为空,并且返回一个布尔值 |
size | 返回队列中的元素数 |
注:queue没有提供begin()和end()函数,所以不能使用迭代器,因此无法将STL算法用于queue。这样设计,也是为了queue类只能进行符合队列行为的操作。
下面举例使用一些成员函数,演示常见的队列操作:
#include <iostream>
#include <queue>
using namespace std;
int main()
{
queue<int> nums; // 实例化一个整型队列nums,用来存放int类型元素
cout<<"依次将1、5、10、15插入队尾"<<endl;
nums.push(1);
nums.push(5);
nums.push(10);
nums.push(15);
cout<<"队列nums包含元素的个数:"<<nums.size()<<endl;
cout<<"队列nums首元素是:"<<nums.front<<endl;
cout<<"队列nums尾元素是:"<<nums.back()<<endl;
mums.pop();
mums.pop();
mums.pop();
mums.pop();
if(nums.empty())
cout<<"该队列是空的!"<<endl;
return 0;
}
3. 优先级队列priority_queue类
priority_queue与queue的不同之处在于,包含最大值的元素位于队首,且只能在队首执行操作。priority_queue类是一个模板类,使用它之前,也必须包含头文件:
#include <queue>
(1) 实例化priority_queue类
std::priority_queue类的定义如下:
template<
class elementType,
class Container=vector<Type>,
class Compare=less<typename Container::value_type>
>
>class priority_queue
解释:
1. elementType 指定了优先级队列包含元素的类型
2. Container 是priority_queue用于存储元素的集合类型,默认是vector,也可将该参数设置为list、deque。
3. Compare 用来指定一个二元谓词,以判断哪个元素位于队首。如果没有指定二元谓词,将默认使用std::less,它使用运算符<比较对象。
注:二元谓词是:返回bool型,帮助决策的二元函数。二元谓词可用于std::sort()等排序算法中。
创建一个元素类型为int,按从小到大顺序存储的队列,且指定存储的容器为deque:
priority_queue <int, deque<int>, greater<int>> nums;
如果想改变存储的顺序,希望从大到小存储;只需将greater改为less:
priority_queue <int, deque<int>, less<int>> nums;
下面演示了几种不同的实例化方法:
#include <iostream>
#include <queue>
using namespace std;
int main()
{
//1. 实例化一个整型优先队列nums,用来存放int类型元素
priority_queue<int> nums;
//2. 实例化一个浮点型优先队列doubleNums
priority_queue<double> doubleNums;
//3. 创建一个元素类型为int,按从小到大顺序存储的队列,且指定存储的容器为deque
priority_queue <int, deque<int>, greater<int>> nums;
//4. 使用一个优先级队列nums去实例化另一个优先级队列numsCopy
priority_queue<int> numsCopy(nums);
return 0;
}
(2) priority_queue的成员函数
与queue不同的是,priority_queue没有提供front()和back(),但是提供了top()来访问优先级队列的成员。
下表列出了常用的queue的成员函数:
成员函数 | 功能 |
---|---|
push | 在优先级队列尾新添一个元素 |
pop | 将优先级队首的第一个元素删除 |
empty | 检查优先级队列是否为空,并且返回一个布尔值 |
size | 返回优先级队列中的元素数 |
top | 返回指向队首第一个元素(最大元素)的引用 |
注:当使用默认的二元谓词std::less时,top()返回的是最大元素;当指定二元谓词是greater,即从小到大的顺序存储,则top()返回的值是最小元素。
下面举一个简单的示例:使用二元谓词greater实例化一个优先级队列。
#include <iostream>
#include <queue>
using namespace std;
int main()
{
//创建一个元素类型为int,按从小到大顺序存储的优先级队列
priority_queue <int, deque<int>, greater<int>> nums;
cout<<"向优先级队列中依次插入1、5、-10、100"<<endl;
nums.push(1);
nums.push(5);
nums.push(-10);
nums.push(100);
cout<<"该队列中的元素一共有:"<<nums.size()<<endl;
while(!nums.empty())
{
cout<<"删除队首的第一个元素:"<<nums.top()<<endl;
nums.pop();
}
return 0;
}
相关文章推荐
【算法与数据结构 06】先进先出的队列 —— 顺序队列 || 循环队列 || 链式队列 大盘点
转载:https://blog.csdn.net/wjinjie/article/details/108126720