【C++】-- STL容器适配器之queue

简介: 【C++】-- STL容器适配器之queue

队列

1.队列的性质

(1)队列是一种容器适配器,容器适配器即将特定容器类封装作为其底层容器类,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端删除元素。

(2) 队列作为容器适配器实现,queue提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。

(3)底层容器可以是标准容器类模板之一,如可用vector、list可以作为底层容器类,也可以是其他专门设计的容器类,。该底层容器应至少支持以下操作:

       empty:检测队列是否为空

       size:返回队列中有效元素的个数

       front:返回队头元素的引用

       back:返回队尾元素的引用

       push_back:在队列尾部入队列

       pop_front:在队列头部出队列

(4)标准容器类deque和list满足了这些要求。默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque。

2.队列类

(1)队列的构造

构造一个队列:

explicit queue (const container_type& ctnr = container_type());//构造一个队列

构造一个队列q1:

queue<int> q1;//构造一个空队列q1

(2)empty( )

判断队列是否为空

bool empty() const;

判断队列q1是否为空:

cout << q1.empty() << endl;

(3)push( )

向队尾插入一个元素

void push (const value_type& val);

向队尾插入4个元素,值分别为1,2,3,4

1.  q1.push(1);
2.  q1.push(2);
3.  q1.push(3);
4.  q1.push(4);

(4)pop( )

从队头删除一个元素

void pop();

删除队头元素

(5) size( )

求队列中元素的个数

size_type size() const;

求q1中元素个数:

cout << q1.size() << endl;

 

(6)front( )

返回队头元素

1. value_type& front();
2. const value_type& front() const;

返回q1队头元素:

cout << q1.front() << endl;

(7)back( )

返回队尾元素

1. value_type& back();
2. const value_type& back() const;

返回q1队尾元素:

cout << q1.back() << endl;

2.队列模拟实现

queue类的定义:

template <class T, class Container = deque<T> > class queue;

其中deque作为双端队列,queue如果没有指定底层容器为list等,那么会默认底层容器为deque。队列作为容器适配器, 不像string、vector、list等是完整的容器类,队列不是完整的容器类,而是提供特定接口的类,相当于在完整容器外面包装了一层,比如使用deque或list实现队列,就可以借助deque或list的操作来实现队列的操作。

队列的构造函数、拷贝构造函数、赋值运算符重载函数、析构函数不需要写,会调用deque自己的默认构造函数、拷贝构造函数、赋值运算符重载函数、析构函数。

017-queue.h

1. #pragma once
2. #include<iostream>
3. #include<deque>
4. using namespace std;
5. 
6. namespace delia
7. {
8.  template <class T, class Container = deque<T>>
9.  class queue
10.   {
11.   public:
12. 
13.     //向队尾插入一个元素
14.     void push(const T& x)
15.     {
16.       _con.push_back(x);
17.     }
18. 
19.     //从队头删除一个元素
20.     void pop()
21.     {
22.       _con.pop_front();
23.     }
24. 
25.     //返回队头元素
26.     T front()
27.     {
28.       return _con.front();
29.     }
30. 
31.     //返回队尾元素
32.     T back()
33.     {
34.       return _con.back();
35.     }
36. 
37.     //判断队列是否尾空
38.     bool empty()
39.     {
40.       return _con.empty();
41.     }
42. 
43.     //求队列中元素的个数
44.     size_t size()
45.     {
46.       return _con.size();
47.     }
48. 
49.   private:
50.     Container _con;
51.   };
52. 
53.   void test_queue()
54.   {
55.     queue<int> q1;
56.     q1.push(1);
57.     q1.push(2);
58.     q1.push(3);
59.     q1.push(4);
60. 
61.     q1.pop();//删除队头元素1
62. 
63.     cout << q1.front() << endl;//打印q1队头元素
64.     cout << q1.back() << endl;//打印q1队尾元素
65.     cout << q1.empty() << endl;//判断q1是否为空
66.     cout << q1.size() << endl;//求q1元素个数
67.   }
68. }

017-test.cpp

1. #include "017-queue.h"
2. 
3. int main()
4. {
5.  delia::test_queue();
6.  return 0;
7. }

假如底层不想用deque实现,但是不能用vector实现,因为队列的删除操作就是删除vector顺序表第一个元素,那么后面所有的元素都需要向前挪,效率低。可以用list实现,队列的删除操作就是修改头节点的_next指向和第2个节点的_prev指向,效率高。因此只需要修改第3行和第8行,将deque改为list即可:

1. #pragma once
2. #include<iostream>
3. #include<list>
4. using namespace std;
5. 
6. namespace delia
7. {
8.  template <class T, class Container = list<T>>
9.  class queue
10.   {
11.   public:
12. 
13.     //向队尾插入一个元素
14.     void push(const T& x)
15.     {
16.       _con.push_back(x);
17.     }
18. 
19.     //从队头删除一个元素
20.     void pop()
21.     {
22.       _con.pop_front();
23.     }
24. 
25.     //返回队头元素
26.     T front()
27.     {
28.       return _con.front();
29.     }
30. 
31.     //返回队尾元素
32.     T back()
33.     {
34.       return _con.back();
35.     }
36. 
37.     //判断队列是否尾空
38.     bool empty()
39.     {
40.       return _con.empty();
41.     }
42. 
43.     //求队列中元素的个数
44.     size_t size()
45.     {
46.       return _con.size();
47.     }
48. 
49.   private:
50.     Container _con;
51.   };
52. 
53.   void test_queue()
54.   {
55.     queue<int> q1;
56.     q1.push(1);
57.     q1.push(2);
58.     q1.push(3);
59.     q1.push(4);
60. 
61.     q1.pop();//删除队头元素1
62. 
63.     cout << q1.front() << endl;//打印q1队头元素
64.     cout << q1.back() << endl;//打印q1队尾元素
65.     cout << q1.empty() << endl;//判断q1是否为空
66.     cout << q1.size() << endl;//求q1元素个数
67.   }
68. }


相关文章
|
6月前
|
缓存 算法 程序员
C++STL底层原理:探秘标准模板库的内部机制
🌟蒋星熠Jaxonic带你深入STL底层:从容器内存管理到红黑树、哈希表,剖析迭代器、算法与分配器核心机制,揭秘C++标准库的高效设计哲学与性能优化实践。
C++STL底层原理:探秘标准模板库的内部机制
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
342 2
|
存储 算法 C++
【c++丨STL】map/multimap的使用
本文详细介绍了STL关联式容器中的`map`和`multimap`的使用方法。`map`基于红黑树实现,内部元素按键自动升序排列,存储键值对,支持通过键访问或修改值;而`multimap`允许存在重复键。文章从构造函数、迭代器、容量接口、元素访问接口、增删操作到其他操作接口全面解析了`map`的功能,并通过实例演示了如何用`map`统计字符串数组中各元素的出现次数。最后对比了`map`与`set`的区别,强调了`map`在处理键值关系时的优势。
687 73
|
存储 算法 C++
【c++丨STL】set/multiset的使用
本文深入解析了STL中的`set`和`multiset`容器,二者均为关联式容器,底层基于红黑树实现。`set`支持唯一性元素存储并自动排序,适用于高效查找场景;`multiset`允许重复元素。两者均具备O(logN)的插入、删除与查找复杂度。文章详细介绍了构造函数、迭代器、容量接口、增删操作(如`insert`、`erase`)、查找统计(如`find`、`count`)及`multiset`特有的区间操作(如`lower_bound`、`upper_bound`、`equal_range`)。最后预告了`map`容器的学习,其作为键值对存储的关联式容器,同样基于红黑树,具有高效操作特性。
551 3
|
8月前
|
Kubernetes Docker Python
Docker 与 Kubernetes 容器化部署核心技术及企业级应用实践全方案解析
本文详解Docker与Kubernetes容器化技术,涵盖概念原理、环境搭建、镜像构建、应用部署及监控扩展,助你掌握企业级容器化方案,提升应用开发与运维效率。
1127 108
|
9月前
|
存储 监控 测试技术
如何将现有的应用程序迁移到Docker容器中?
如何将现有的应用程序迁移到Docker容器中?
666 57
|
6月前
|
监控 Kubernetes 安全
还没搞懂Docker? Docker容器技术实战指南 ! 从入门到企业级应用 !
蒋星熠Jaxonic,技术探索者,以代码为笔,在二进制星河中书写极客诗篇。专注Docker与容器化实践,分享从入门到企业级应用的深度经验,助力开发者乘风破浪,驶向云原生新世界。
705 51
还没搞懂Docker? Docker容器技术实战指南 ! 从入门到企业级应用 !