深入探讨【C++容器适配器】:现代编程中的【Stack与Queue】的实现

目录

一、Stack(栈)

1.1 Stack的介绍

1.2 Stack的使用

1.3 Stack的模拟实现

二、Queue(队列)

2.1 Queue的介绍

2.2 Queue的使用

2.3 Queue的模拟实现

三、容器适配器

3.1 什么是适配器

3.2 为什么选择deque作为stack和queue的底层默认容器

​编辑

总结


 

专栏:C++学习笔记 

上一卷:C++—list容器

在C++中,stackqueue是两种非常重要的数据结构,广泛应用于各种算法和系统中。本文将详细介绍这两种数据结构的基本概念、使用方法及其底层实现,并结合代码示例和运行结果进行详细讲解。

一、Stack(栈)

1.1 Stack的介绍

stack(栈)是一种容器适配器,专门用于后进先出(LIFO, Last In First Out)的操作环境中。栈的元素插入和删除操作只能在容器的一端进行,即栈顶。

栈的底层容器可以是任何标准的容器类模板或一些其他特定的容器类,这些容器类应支持以下操作:

  • empty(): 判空操作
  • back(): 获取尾部元素操作
  • push_back(): 尾部插入元素操作
  • pop_back(): 尾部删除元素操作

标准容器vectordequelist均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器,默认情况下使用deque

小李的理解:
栈就像是一叠盘子,你只能从顶部添加或移除盘子。这就意味着最后添加的盘子最先被移除(后进先出)。在C++中,栈的底层可以用多种容器实现,但一般默认用deque,因为它支持高效的尾部操作。

1.2 Stack的使用

stack的常用操作包括:

  • stack(): 构造空的栈
  • empty(): 检测stack是否为空
  • size(): 返回stack中元素的个数
  • top(): 返回栈顶元素的引用
  • push(val): 将元素val压入stack中
  • pop(): 将stack中尾部的元素弹出

示例代码

#include <stack>
#include <iostream>int main() {std::stack<int> s;s.push(1);s.push(2);s.push(3);std::cout << "Stack top: " << s.top() << std::endl; // 输出3s.pop();std::cout << "Stack top after pop: " << s.top() << std::endl; // 输出2return 0;
}

首先我们压入了三个元素1, 2, 3,栈顶元素是3。然后我们弹出了栈顶元素,栈顶变成了2。

小李的理解:
就像把三个盘子按顺序叠起来(1在最底下,3在最上面)。当我们移走最上面的盘子时,下面的盘子就成了新的顶部。

1.3 Stack的模拟实现

从栈的接口中可以看出,栈实际是一种特殊的vector,因此使用vector完全可以模拟实现stack

示例代码

#include <vector>
#include <iostream>namespace bite {template<class T>class stack {public:stack() {}void push(const T& x) { _c.push_back(x); }void pop() { _c.pop_back(); }T& top() { return _c.back(); }const T& top() const { return _c.back(); }size_t size() const { return _c.size(); }bool empty() const { return _c.empty(); }private:std::vector<T> _c;};
}int main() {bite::stack<int> s;s.push(1);s.push(2);s.push(3);std::cout << "Custom stack top: " << s.top() << std::endl; // 输出3s.pop();std::cout << "Custom stack top after pop: " << s.top() << std::endl; // 输出2return 0;
}

这表明我们的自定义stack实现与标准库中的行为一致。

小李的理解:
我们自己实现了一个简单的栈,用vector来存储元素。每次添加元素时,将它们推到vector的尾部;每次移除元素时,从vector的尾部移除。这和我们平时用的栈行为完全一样。

二、Queue(队列)

2.1 Queue的介绍

queue(队列)是一种容器适配器,专门用于先进先出(FIFO, First In First Out)的操作环境中。队列的元素插入操作在容器的一端进行,即队尾,而提取操作在容器的另一端进行,即队头。

队列的底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。这些容器类应支持以下操作:

  • empty(): 检测队列是否为空
  • size(): 返回队列中有效元素的个数
  • front(): 返回队头元素的引用
  • back(): 返回队尾元素的引用
  • push_back(): 在队列尾部插入元素
  • pop_front(): 在队列头部删除元素

标准容器dequelist满足这些要求。默认情况下,如果没有为queue指定特定的底层容器,则使用deque

小李的理解:
队列就像排队买票,最早来的人最先买到票(先进先出)。在C++中,队列的底层可以用多种容器实现,但一般默认用deque,因为它支持高效的头尾操作。

2.2 Queue的使用

queue的常用操作包括:

  • queue(): 构造空的队列
  • empty(): 检测队列是否为空
  • size(): 返回队列中有效元素的个数
  • front(): 返回队头元素的引用
  • back(): 返回队尾元素的引用
  • push(val): 在队尾将元素val入队列
  • pop(): 将队头元素出队列

示例代码

#include <queue>
#include <iostream>int main() {std::queue<int> q;q.push(1);q.push(2);q.push(3);std::cout << "Queue front: " << q.front() << std::endl; // 输出1q.pop();std::cout << "Queue front after pop: " << q.front() << std::endl; // 输出2return 0;
}

首先我们压入了三个元素1, 2, 3,队头元素是1。然后我们弹出了队头元素,队头变成了2。

小李的理解:
就像排队买票,第一个人买了票离开,第二个人就成了最前面的人。

2.3 Queue的模拟实现

因为queue的接口中存在头删和尾插,因此使用vector来封装效率太低,故可以借助list来模拟实现queue

示例代码

#include <list>
#include <iostream>namespace bite {template<class T>class queue {public:queue() {}void push(const T& x) { _c.push_back(x); }void pop() { _c.pop_front(); }T& back() { return _c.back(); }const T& back() const { return _c.back(); }T& front() { return _c.front(); }const T& front() const { return _c.front(); }size_t size() const { return _c.size(); }bool empty() const { return _c.empty(); }private:std::list<T> _c;};
}int main() {bite::queue<int> q;q.push(1);q.push(2);q.push(3);std::cout << "Custom queue front: " << q.front() << std::endl; // 输出1q.pop();std::cout << "Custom queue front after pop: " << q.front() << std::endl; // 输出2return 0;
}

 

这表明我们的自定义queue实现与标准库中的行为一致。

小李的理解:
我们自己实现了一个简单的队列,用list来存储元素。每次添加元素时,将它们推到list的尾部;每次移除元素时,从list的头部移除。这和我们平时用的队列行为完全一样。

三、容器适配器

3.1 什么是适配器

适配器是一种设计模式,该模式是将一个类的接口转换成客户希望的另外一个接口。在STL中,stackqueue就是通过适配器模式将dequevector等容器类的接口转换成特定的LIFO或FIFO操作。

3.2 为什么选择deque作为stack和queue的底层默认容器

虽然stackqueue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stackqueue只是对其他容器的接口进行了包装,STL中stackqueue默认使用deque。主要原因如下:

  1. stackqueue不需要遍历(因此stackqueue没有迭代器),只需要在固定的一端或者两端进行操作。
  2. stack中元素增长时,dequevector的效率高(扩容时不需要搬移大量数据);queue中的元素增长时,deque不仅效率高,而且内存使用率高。

结合了deque的优点,而完美地避开了其缺陷,使其成为stackqueue的理想底层容器。

总结

C++中的stackqueue通过容器适配器实现,分别用于LIFO和FIFO操作。stackqueue的底层容器默认使用deque,但也可以根据需求选择其他标准容器。理解并灵活运用这些数据结构,对于高效编写算法和处理复杂数据具有重要意义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/44679.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Vue和UCharts的前端组件化开发:实现高效、可维护的词云图与进度条组件

基于Vue和UCharts的前端组件化开发&#xff1a;实现高效、可维护的词云图与进度条组件 摘要 随着前端技术的迅速发展和业务场景的日益复杂&#xff0c;传统的整块应用开发方式已无法满足现代开发的需求。组件化开发作为一种有效的解决方案&#xff0c;能够将系统拆分为独立、…

解决pycharm无法识别miniconda

解决pycharm无法识别miniconda 找到miniconda安装目录下condabin/conda.bat文件&#xff0c;点击load即可识别codna环境 a环境

仕考网:没有学位证能考公务员吗?

公务员考试需要满足报名条件才能参加&#xff0c;没有学位证能考公吗? 没有学位证书的考生也有机会参与公务员考试虽然可以选择的岗位比较少&#xff0c;但可以报考参加那些不设定学位要求的岗位。当发布的公务员招录信息中某一职位的学位要求标注为“无要求”时&#xff0c;…

【C++】:继承[下篇](友元静态成员菱形继承菱形虚拟继承)

目录 一&#xff0c;继承与友元二&#xff0c;继承与静态成员三&#xff0c;复杂的菱形继承及菱形虚拟继承四&#xff0c;继承的总结和反思 点击跳转上一篇文章&#xff1a; 【C】&#xff1a;继承(定义&&赋值兼容转换&&作用域&&派生类的默认成员函数…

MATLAB Gazebo联合仿真

准备仿真环境&#xff1a;在Gazebo中设置仿真场景&#xff0c;包括机器人模型、环境布局、传感器和执行器等。编写MATLAB脚本&#xff1a;在MATLAB中编写控制算法和数据处理脚本&#xff0c;用于接收Gazebo中的传感器数据&#xff0c;并生成控制命令。建立通信&#xff1a;通过…

DEBUG:jeston卡 远程ssh编程

问题 jeston 打开网页 gpt都不方便 而且只需要敲命令就行 解决 下载MobaXterm(window执行) liunx需要虚拟机 软件 远程快速复制命令

vue中table内容和lable对不齐解决方案

问题&#xff1a; 代码片段&#xff1a; <template><el-table :data"tableData" stripe style"width: 100%"><el-table-column prop"title" label"标题" width"80px" /><el-table-column prop"n…

Windows安全日志导致环境内存占用过高

Windows 环境内存占用高不释放&#xff0c;目前遇到的常见情况如下&#xff1a; 情况一&#xff1a;JVM内存泄漏 这种网上的排查方式有很多&#xff0c;自行查阅即可 情况二&#xff1a;SQLserver内存配置过大 这种也是&#xff0c;从网上查找修改方式然后修改即可 情况三…

Defensor 4.5:构建数据资产为中心的安全运营体系

5月31日“向星力”未来数据技术峰会上&#xff0c;星环科技重磅发布数据安全管理平台 Defensor 4.5版本。新版本引入了以数据资产为中心的数据安全运营体系&#xff0c;通过智能化大模型技术&#xff0c;帮助企业快速、精准地识别核心重要资产&#xff1b;建设全局的数据安全策…

MySQL学习记录 —— 십팔 常用程序和配置文件

文章目录 1、mysqld2、mysql常用命令介绍 3、配置文件语法 1、mysqld mysqld就是MySQL服务器&#xff0c;是一个多线程程序。对数据目录&#xff0c;即mysql的主要工作目录进行访问管理。当mysqld启动时&#xff0c;会侦听指定的端口&#xff0c;处理来自客户端程序的网络连接…

【vue教程】二. Vue特性原理详解

目录 回顾本章涵盖知识点Vue 实例和选项创建 Vue 实例Vue 实例的选项 Vue 模板语法插值表达式指令v-bindv-modelv-on 自定义指令创建自定义指令在模板中使用自定义指令自定义指令的钩子函数自定义指令的实例演示 指令注册局部注册指令过滤器 数据绑定和响应式原理响应式数据绑定…

编程题目积累(day5)

题目&#xff1a; 源数组a&#xff0c;将a中所有元素乘以2之后添加进a&#xff0c;则这个a就叫双倍数组&#xff0c;给你一个数组a&#xff0c;判断它是不是双倍数组&#xff0c;如果是则输出源数组&#xff0c;不是则输出空数组。 补充知识&#xff1a; python中枚举和字典…

【python数据结构精讲】双端队列

通过总结《流畅的Python》等书中的知识&#xff0c;总结Python中常用工具的方法。 deque&#xff0c;学名双端队列。 1. 常用方法 append()&#xff1a;队列尾部添加appendleft()&#xff1a;队首添加pop()&#xff1a;移除队列最后一个元素popleft()&#xff1a;移除队列第一…

AI算法14-套索回归算法Lasso Regression | LR

套索回归算法概述 套索回归算法简介 在统计学和机器学习中&#xff0c;套索回归是一种同时进行特征选择和正则化&#xff08;数学&#xff09;的回归分析方法&#xff0c;旨在增强统计模型的预测准确性和可解释性&#xff0c; 正则化是一种回归的形式&#xff0c;它将系数估…

并发编程-06之Semaphore

一 Semaphore入门 1.1 什么是Semaphore Semaphore&#xff0c;俗称信号量&#xff0c;它是操作系统中PV操作的原语在java的实现&#xff0c;它也是基于AbstractQueuedSynchronizer实现的。 Semaphore的功能非常强大&#xff0c;大小为1的信号量就类似于互斥锁&#xff0c;通过同…

centos部署jar包

第一步&#xff1a; 将IDEA中的项目打包为jar,将这个jar文件放到centos服务器上的目录里&#xff0c;我在opt新建api目录&#xff0c;将jar文件放入&#xff0c;如下图&#xff1a; 第二步&#xff1a; 将需要读取的配置文件也放入此目录(其他目录也可以&#xff0c;和脚本中…

搭建RAG系统就这么简单:LangChain|RAG是什么?

RAG是什么 “RAG”&#xff08;Retrieval-Augmented Generation&#xff09;是一种结合了检索&#xff08;Retrieval&#xff09;和生成&#xff08;Generation&#xff09;的人工智能技术&#xff0c;它在大模型中被需要的原因包括&#xff1a; 知识丰富性&#xff1a; 大模…

探索数据结构与算法的奇妙世界 —— Github开源项目推荐《Hello 算法》

在浩瀚的编程与计算机科学领域中&#xff0c;数据结构与算法无疑是每位开发者攀登技术高峰的必经之路。然而&#xff0c;对于初学者而言&#xff0c;这条路往往布满了荆棘与挑战。幸运的是&#xff0c;今天我要向大家推荐一个令人振奋的项目——《Hello Algo》&#xff0c;它正…

ubuntu使用kubeadm搭建k8s集群

一、卸载k8s kubeadm reset -f modprobe -r ipip lsmod rm -rf ~/.kube/# 自己选择性删除 坑点哦 rm -rf /etc/kubernetes/ rm -rf /etc/systemd/system/kubelet.service.d rm -rf /etc/systemd/system/kubelet.service rm -rf /usr/bin/kube* rm -rf /etc/cni rm -rf /opt/cn…

Prometheus + alermanager + webhook-dingtalk 告警

添加钉钉机器人 1. 部署 alermanager 1.1 下载软件包 wget https://github.com/prometheus/alertmanager/releases/download/v0.26.0/alertmanager-0.26.0.linux-amd64.tar.gz 网址 &#xff1a;Releases prometheus/alertmanager (github.com) 1.2 解压软件包 mkdir -pv …