目录
🤔queue模板介绍:
🤔queue特点:
🤔queue内存图解:
🤔 queue的成员函数
🔍queue构造函数:
🔍queue赋值函数:
🔍queue判断函数:
🔍queue删除和添加函数:
🤔代码验证:
🤔运行结果:
🤔queue实际应用场景:
🤔结束!
🤔queue模板介绍:
queue(队列)是一种数据结构,它可以在一端插入元素,另一端弹出元素,并且按照元素被放入队列的顺序进行访问。在队列中插入元素的一端叫做队尾(rear),从队列中弹出元素的一端叫做队首(front)。队列的典型应用包括广度优先搜索和缓存。
在C++ STL中,队列实现为一个模板类,称为queue。它包含以下操作:
📖1. push(x):将元素x插入队列尾部。
📖2. pop():弹出队列头部元素。
📖3. front():返回队列头部元素。
📖4. back():返回队列尾部元素。
📖5. empty():检查队列是否为空。
📖6. size():返回队列中元素的数量。
📖7.emplace(x) :将元素x插入队列尾部。
🤔queue特点:
📖1.不支持迭代器:不可以用下标访问队列。
📖2.插入和删除:只允许从一端新增元素,从另一端移除元素。
📖3.访问操作:只有队头和队尾接受访问,其余数据不可访问。
在C++17标准以后,queue模板新增函数emplace;它和push()的作用类似,都是将一个数据压入队尾,但是相比较于push来讲,emplace不需要创建一个临时对象,而是直接在容器内构造一个元素。相对于push()
函数,我们需要先创建一个元素对象,然后将其复制到容器中或者移动到容器中,这将导致更多的开销,特别是在元素类型比较大或者包含不可复制/移动的对象时。
另外,emplace的高效性还得益于容器中可能的内部优化。对于某些容器(如vector
),如果容器中没有足够的空间来存储新增的元素,容器可能会重新分配一块更大的内存,并将现有元素移动到新的内存中。在这样的情况下,使用emplace函数可以直接在新分配的内存中构造元素,而不需要先构造临时对象,再将其复制到新的内存中,这将节省大量的时间和空间。
当然,需要注意的是,对于某些简单类型的元素(如整数、浮点数等),由于它们的构造和复制开销比较小,因此emplace和push()
在执行速度上的差异将比较小。但在任何情况下,使用emplace可以使代码更加简洁和高效。
🤔queue内存图解:
🤔 queue的成员函数
🔍queue构造函数:
📖1.默认构造函数:queue<T>que
queue<int> d;
📖2.拷贝构造函数:queue(const queue &que) *此处是深拷贝,不共用地址
queue<int>d1(d);
🔍queue赋值函数:
📖1.重载等号运算符:queue &operator =(const queue &que)
queue<int>d2;
d2 = d;
🔍queue判断函数:
📖1.判断队列是否为空:empty()
q.empty();
📖2.返回队的大小:size()
q.size()
📖3.交换两个队列:swap()
d.swap();
🔍queue删除和添加函数:
📖1.向队尾添加元素:push()
d.push(i);
📖2.向队尾添加,任何时候比push更加高效:emplace()
d.emplace(999);
📖3.返回队尾元素:back()
d.back();
📖4.返回队头元素:front()
d.front();
🤔代码验证:
#include<iostream>
#include<queue>
using namespace std;
void print( queue<int>& q)
{
cout << endl;
cout << "队的大小为:";
cout << q.size()<<endl;
//利用判断队列是否为空来进行循环
while (!q.empty()) {
cout << q.front() << " ";
q.pop(); // 删除队列头元素
}
cout << endl;
cout << "队的大小为:";
cout << q.size()<<endl;
cout << endl;
}
void test01()
{
//默认构造
queue<int> d;
for (int i = 0; i < 10; i++)
{
d.push(i);
}
cout << "默认构造的结果为";
print(d);
//因为队列d已经被清空,我们需要再次进行入队操作
for (int i = 0; i < 10; i++)
{
d.push(i);
}
//拷贝构造函数(深拷贝)
queue<int>d1(d);
cout << "拷贝构造的结果为";
print(d1);
//赋值函数
queue<int>d2;
d2 = d;
cout << "赋值函数的结果是:";
print(d2);
cout << "d的第一个元素为:";
cout << d.front() << endl;
cout << "d的最后一个元素为:";
cout << d.back();
//利用emplace添加元素
d.emplace(999);
print(d);
}
int main()
{
test01();
}
🤔运行结果:
🤔queue实际应用场景:
queue 模板常用于以下情况:
📖1. 宽度优先搜索:在算法中,queue 是广度优先搜索 (BFS) 的核心数据结构,用于存储待处理的节点和处理顺序。BFS 算法在社交网络、推荐系统、游戏 AI 等许多应用中都有着广泛的应用。
📖2. 消息队列:在计算机中,队列是消息传递系统的核心数据结构之一,用于在进程之间传输数据。常见的例子包括消息队列和事件循环系统。
📖3. 带有限制大小的缓存:在某些场景下,我们需要维护一个带有限制大小的缓存,当缓存满时,需要删除一些早期添加的数据。queue 模板提供了此类场景的完美解决方案
📖4. 多线程队列:在多线程编程中,queue 模板也被广泛使用,它可以用于协调不同线程之间的工作。比如,一个线程负责生产数据,将其压入队列中,另一个线程负责消费队列中的数据。通常,在多线程环境中使用 queue 模板需要使用线程安全的数据结构,例如 std::mutex 原子操作等。
📖综上所述,queue 模板作为一种线性数据结构,具有广泛的应用场景,特别是在需要按照先进先出 (FIFO) 或者后进先出 (LIFO) 条件访问数据的情况下。