【c++丨STL】stack和queue的使用及模拟实现
🌟🌟作者主页:ephemerals__
🌟🌟所属专栏:C++、STL
目录
前言
一、什么是容器适配器
二、stack的使用及模拟实现
1. stack的使用
empty
size
top
push和pop
swap
2. stack的模拟实现
三、queue的使用及模拟实现
1. queue的使用
empty
size
front和back
push和pop
swap
2. queue的模拟实现
总结
前言
本篇文章,博主将介绍STL中两个比较重要的容器适配器:stack(栈)和queue(队列)以及它们的使用方法,并且尝试模拟实现它们。如果你不是很了解栈和队列这两种数据结构,可以参阅这篇文章:
【数据结构】栈和队列(c语言实现)(附源码)_创建栈和队列及使用代码-CSDN博客
正文开始
一、什么是容器适配器
与vector、list这些容器不同,stack和queue被称作容器适配器。所谓容器适配器,就是指在一种已有的容器基础上,为其添加了一些新的特性或者功能,目的是使一事物的行为类似于另一类事物。
例如栈这一数据结构,它的本质其实就是对顺序表或者链表的功能进行了一些限制,例如无法遍历、只能在一端进出数据等,但其底层仍然是顺序结构或是链式结构。STL在设计stack和queue时,并没有从零开始构建它们的底层结构,而是采用了这种设计思想,对现有容器进行了封装,从而实现了它们。
接下来,我们看看SGI版本的STL源码的stack实现:
可以看到,源码使用了一个叫做deque的容器创建对象,然后调用该对象的一些接口来实现stack的接口。之后模拟实现stack和queue的过程中,我们也将遵循源码的设计思路,对其他容器(例如vector和list)进行封装。
关于deque(双端队列)的底层结构,博主将在后续文章中讲解。
二、stack的使用及模拟实现
接下来,我们正式开始学习stack的使用方法,并尝试模拟实现。
1. stack的使用
stack的成员函数如下:
注意:容器适配器是不支持遍历的,所以它们没有迭代器接口。
empty
empty的作用是判断栈是否为空,若为空则返回true,否则返回false。
代码示例:
#include <iostream>
#include <stack>
#include <queue>
using namespace std;int main()
{stack<int> s1;stack<int> s2;s2.push(1);//压入一个元素cout << s1.empty() << endl;cout << s2.empty() << endl;return 0;
}
size
size用于获取栈中元素个数。
代码示例:
#include <iostream>
#include <stack>
#include <queue>
using namespace std;int main()
{stack<int> s;s.push(1);s.push(1);s.push(1);cout << s.size() << endl;return 0;
}
top
top用于获取栈顶元素。 代码示例:
#include <iostream>
#include <stack>
#include <queue>
using namespace std;int main()
{stack<int> s;s.push(10);cout << s.top() << endl;return 0;
}
push和pop
push的功能是将数据压入栈顶,而pop可以将栈顶元素弹出。
使用举例:
#include <iostream>
#include <stack>
#include <queue>
using namespace std;int main()
{stack<int> s;for (int i = 1; i <= 10; i++)//循环压入十个元素{s.push(i);}while (!s.empty())//栈非空则循环出栈{cout << s.top() << ' ';s.pop();//出栈}return 0;
}
swap
swap用于交换两个栈的内容。
2. stack的模拟实现
stack的模拟实现也比较简单,由于我们之前使用顺序结构来实现栈,那么我们就将vector作为封装容器。代码如下:
#include <iostream>
#include <vector>
using namespace std;template<class T, class Container = vector<T>>//模板参数默认为vector
class Stack
{
public://压栈void push(const T& x){_con.push_back(x);//调用vector的尾插}//出栈void pop(){_con.pop_back();//调用vector的尾删}//取栈顶元素const T& top() const{return _con.back();//调用vector的获取尾元素}//判空bool empty() const{return _con.empty();//调用vector的empty}//获取元素个数size_t size() const{return _con.size();//调用vector的size}//交换void swap(Stack<T>& s){_con.swap(s._con);//调用vector的交换函数}
private:Container _con;//成员容器
};
三、queue的使用及模拟实现
在掌握了stack的使用与模拟实现之后,我们为大家介绍queue的使用及模拟实现。
1. queue的使用
queue的成员函数如下:
empty
empty用于判断队列是否为空。若为空则返回true,否则返回flase。
代码示例:
#include <iostream>
#include <stack>
#include <queue>
using namespace std;int main()
{queue<int> q1;queue<int> q2;q1.push(1);cout << q1.empty() << endl;cout << q2.empty() << endl;return 0;
}
size
size用于获取队列中的元素个数。代码示例:
#include <iostream>
#include <stack>
#include <queue>
using namespace std;int main()
{queue<int> q;q.push(1);q.push(1);q.push(1);q.push(1);q.push(1);cout << q.size() << endl;return 0;
}
front和back
front和back分别用于获取对头/队尾元素。代码示例:
#include <iostream>
#include <stack>
#include <queue>
using namespace std;int main()
{queue<int> q;q.push(1);q.push(2);q.push(3);q.push(4);q.push(5);cout << q.front() << endl;cout << q.back() << endl;return 0;
}
push和pop
push和pop分别用于进行入队/出队操作。注意对头出队,队尾入队。
代码示例:
#include <iostream>
#include <stack>
#include <queue>
using namespace std;int main()
{queue<int> q;for (int i = 1; i <= 10; i++){q.push(i);}while (!q.empty()){cout << q.front() << ' ';q.pop();}return 0;
}
swap
swap用于交换两个队列的内容。
2. queue的模拟实现
接下来,我们尝试模拟实现queue。由于list具有头删和尾插的接口,我们就将list作为封装容器。代码实现如下:
#include <iostream>
#include <list>
using namespace std;template<class T, class Container = list<T>>//模板参数默认为list
class Queue
{
public://入队void push(const T& x){_con.push_back(x);//调用list的尾插}//出队void pop(){_con.pop_front();//调用list的头删}//取队头元素const T& front(){return _con.front();//调用list的front}//取队尾元素const T& back(){return _con.back();//调用list的back}//获取元素个数size_t size(){return _con.size();//调用list的size}//判空bool empty(){return _con.empty();//调用list的empty}//交换void swap(Queue<T>& q){_con.swap(q._con);//交换两个成员容器的内容}
private:Container _con;//成员容器
};
总结
今天我们学习了STL两个适配器:stack和queue的使用及模拟实现。不难发现,容器适配器的实现思路显著提高了正确率和代码复用率。 如果你觉得博主讲的还不错,就请留下一个小小的赞在走哦,感谢大家的支持❤❤❤
相关文章:

【c++丨STL】stack和queue的使用及模拟实现
🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:C、STL 目录 前言 一、什么是容器适配器 二、stack的使用及模拟实现 1. stack的使用 empty size top push和pop swap 2. stack的模拟实现 三、queue的…...

基于SpringBoot的在线教育系统【附源码】
基于SpringBoot的在线教育系统 效果如下: 系统登录页面 系统管理员主页面 课程管理页面 课程分类管理页面 用户主页面 系统主页面 研究背景 随着互联网技术的飞速发展,线上教育已成为现代教育的重要组成部分。在线教育系统以其灵活的学习时间和地点&a…...

Kafka-副本分配策略
一、上下文 《Kafka-创建topic源码》我们大致分析了topic创建的流程,为了保持它的完整性和清晰度。细节并没有展开分析。下面我们就来分析下副本的分配策略以及副本中的leader角色的确定逻辑。当有了副本分配策略,才会得到分区对应的broker,…...

市场波动不断,如何自我提高交易心理韧性?
交易市场,一个由无数变量交织而成的复杂领域,常常因各方因素的微妙变化而掀起波澜。在这里,机遇与挑战并存,诱人的利润与潜在的风险如影随形,共同考验着每一位交易员的智慧与心理承受能力。在这样的环境下,…...

加速科技精彩亮相中国国际半导体博览会IC China 2024
11月18日—20日,第二十一届中国国际半导体博览会(IC China 2024)在北京国家会议中心顺利举办,加速科技携重磅产品及全系测试解决方案精彩亮相,加速科技创始人兼董事长邬刚受邀在先进封装创新发展论坛与半导体产业前沿与…...

利用c语言详细介绍下选择排序
选择排序(Selection sort)是一种简单直观的排序算法。它是每次选出最小或者最大的元素放在开头或者结尾位置(采用升序的方式),最终完成列表排序的算法。 一、图文介绍 我们还是使用数组【10,5,3…...
华为流程L1-L6业务流程深度细化到可执行
该文档主要介绍了华为业务流程的深度细化及相关内容,包括流程框架、建模方法、流程模块描述、流程图建模等,旨在帮助企业构建有效的流程体系,实现战略目标。具体内容如下: 华为业务流程的深度细化 流程层级:华为业务流程分为 L1 - L6 六个层级,L1 为流程大类,L2 为流程…...

bridge-multicast-igmpsnooping
# 1.topo # 2.创建命名空间 ip netns add ns0 ip netns add ns1 ip netns add ns2 ip netns add ns3 # 3.创建veth设备 ip link add ns0-veth0 type veth peer name hn0-veth0 ip link add ns1-veth0 type veth peer name hn1-veth0 ip link add ns2-veth0 type veth pe…...

git使用(一)
git使用(一) 为什么学习git?两种版本控制系统在github上创建一个仓库(repository)windows上配置git环境在Linux上配置git环境 为什么学习git? 代码写了好久不小心删了,可以使用git防止,每写一部分代码通…...

Linux环境安装MongoDB
文章目录 1. 查看Linux系统的发行版本2. 下载MongoDB3. 安装MongoDB3.1 新建几个目录,分别用来存储 MongoDB 的数据和日志3.2 新建日志文件3.3 新建配置文件 4. 将MongoDB注册为服务4.1 新建服务文件4.2 编写服务文件 5. MongoDB服务相关操作5.1 启动MongoDB服务5.2…...

Cyberchef使用功能之-多种压缩/解压缩操作对比
cyberchef的compression操作大类中有大量的压缩和解压缩操作,每种操作的功能和区别是什么,本章将进行讲解,作为我的专栏《Cyberchef 从入门到精通教程》中的一篇,详见这里。 关于文件格式和压缩算法的理论部分在之前的文章《压缩…...
TypeScript 装饰器都有那些应用场景?如何更快的上手?
TypeScript 装饰器简介 在 TypeScript 中,装饰器(Decorators)是一种特殊的语法,用于在类、类方法、属性、访问器等上动态地添加行为或修改现有行为。装饰器可以用来增强类的功能、修改方法的行为,或者修改类的元数据等…...
堆优化版本的Prim
prim和dijkstra每轮找最小边的松弛操作其实是同源的,因而受dijkstra堆优化的启发,那么prim也可以采用小根堆进行优化。时间复杂度也由 O ( n 2 ) O(n^2) O(n2)降为 O ( n l o g n ) O(nlogn) O(nlogn)。 测试一下吧:原题链接 #include <i…...

Ubuntu上安装MySQL并且实现远程登录
目录 下载网络工具 查看网络连接 更新系统软件包; 安装mysql数据库 查看mysql数据库状态 以数字ip形式显示mysql的监听状态。(默认监听端口是3306) 查看安装mysql数据库时系统创建的目录信息。 根据查询到的系统用户名以及随机密码&a…...

蓝桥杯每日真题 - 第21天
题目:(空间) 题目描述(12届 C&C B组A题) 解题思路: 转换单位: 内存总大小为 256MB,换算为字节: 25610241024268,435,456字节 计算每个整数占用空间: 每个 32 位整数占用…...

(长期更新)《零基础入门 ArcGIS(ArcMap) 》实验一(下)----空间数据的编辑与处理(超超超详细!!!)
续上篇博客(长期更新)《零基础入门 ArcGIS(ArcMap) 》实验一(上)----空间数据的编辑与处理(超超超详细!!!)-CSDN博客 继续更新 目录 什么是拓扑? 1.3.5道路…...

NLP论文速读(CVPR 2024)|使用DPO进行diffusion模型对齐
论文速读|Diffusion Model Alignment Using Direct Preference Optimization 论文信息: 简介: 本文探讨的背景是大型语言模型(LLMs)通过人类比较数据和从人类反馈中学习(RLHF)的方法进行微调,以…...

操作系统——揭开盖子
计算机执行时——取指执行 es:bx等于从0x9000开始,到0x90200结束...
如何在 React 项目中应用 TypeScript?应该注意那些点?结合实际项目示例及代码进行讲解!
在 React 项目中应用 TypeScript 是提升开发效率、增强代码可维护性和可读性的好方法。TypeScript 提供了静态类型检查、自动补全和代码提示等功能,这对于 React 开发者来说,能够帮助早期发现潜在的 bug,提高开发体验。 1. 项目初始化 在现…...

C++学习第四天
创作过程中难免有不足,若您发现本文内容有误,恳请不吝赐教。 提示:以下是本篇文章正文内容,下面案例可供参考 一、计算类对象的大小 #include<iostream> using namespace std;class Date { public:void Init(int year, in…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...