【C++养成计划】队列 —— 快速上手STL queue类(Day13)

写在前面:大家好!我是【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】先进先出的队列 —— 顺序队列 || 循环队列 || 链式队列 大盘点

【C++养成计划】不聊学习只谈干货(Day1)

猜你喜欢

转载自blog.csdn.net/wjinjie/article/details/108126720