C++ stack类与queue类

目录

0.前言

1.容器适配器

1.1容器适配器的特点

1.2容器适配器的实现

1.3使用容器适配器的场景

2.stack的介绍与使用

2.1介绍

2.2使用

3.queue的介绍与使用

3.1介绍

3.2使用

4.stack和queue的模拟实现

4.1 stack的模拟实现

4.2 queue的模拟实现

5.结语


(图像由AI生成)

0.前言

在前面的博客中,我们介绍了STL(Standard Template Library)中的stringvectorlist,这些都是作为“容器”而存在的数据结构。它们各有特点和适用场景,并且都属于独立的容器类型。接下来要介绍的stackqueue,则是“容器适配器”。它们并不是独立的容器,而是通过某些容器来实现特定的行为和接口。因此,它们被称为“容器适配器”。接下来,就让我们一探究竟。

1.容器适配器

容器适配器(Container Adapters)是C++标准模板库(STL)中的一种特殊类别。与常规容器(如vectorlistdeque等)不同,容器适配器不直接管理存储元素的内存,而是基于现有的容器提供一种特定的接口和行为。容器适配器通过限制和修改底层容器的操作来实现其功能。

C++中主要的容器适配器有三种:stackqueuepriority_queue。它们分别适用于不同的场景:

  1. stack:实现后进先出(LIFO,Last In First Out)数据结构。
  2. queue:实现先进先出(FIFO,First In First Out)数据结构。
  3. priority_queue:实现元素按优先级排序的队列,允许最高优先级的元素先出队。

1.1容器适配器的特点

  • 基于现有容器:容器适配器是基于已有容器(如dequelistvector)实现的。这意味着它们依赖于这些底层容器的存储和操作机制。
  • 限制接口:容器适配器通过限制底层容器的操作接口来实现特定的数据结构行为。例如,stack只允许访问栈顶元素,不允许随机访问其他元素。
  • 一致性接口:所有容器适配器都提供一致的接口,这使得它们在使用上更加简洁和统一。

1.2容器适配器的实现

容器适配器通过组合现有容器类,并对其进行包装,实现特定的接口。以下是一个自定义的容器适配器MyAdapter的简化实现:

#include <iostream>
#include <deque>template <typename T, typename Container = std::deque<T>>
class MyAdapter {
private:Container c;
public:// 类型定义typedef typename Container::value_type value_type;typedef typename Container::size_type size_type;typedef typename Container::reference reference;typedef typename Container::const_reference const_reference;// 构造函数explicit MyAdapter(const Container& cont = Container()) : c(cont) {}// 成员函数bool isEmpty() const { return c.empty(); }size_type getSize() const { return c.size(); }reference getFirst() { return c.front(); }const_reference getFirst() const { return c.front(); }void add(const value_type& value) { c.push_back(value); }void removeFirst() { c.pop_front(); }
};int main() {MyAdapter<int> adapter;adapter.add(1);adapter.add(2);adapter.add(3);std::cout << "First element: " << adapter.getFirst() << std::endl;adapter.removeFirst();std::cout << "First element after removal: " << adapter.getFirst() << std::endl;return 0;
}

在这个简化的实现中,MyAdapter类是一个模板类,它基于Container(默认为deque)实现。通过限制Container的操作接口,实现了特定的行为:

  • isEmpty():检查容器是否为空。
  • getSize():获取容器中的元素数量。
  • getFirst():访问容器中的第一个元素。
  • add():向容器中添加元素。
  • removeFirst():移除容器中的第一个元素。

1.3使用容器适配器的场景

容器适配器在实际开发中有广泛的应用场景。例如:

  • 递归和回溯算法:在递归和回溯算法中,stack常用于保存临时状态和返回地址。
  • 任务调度queue常用于实现任务调度,按顺序处理任务。
  • 优先级调度priority_queue常用于实现优先级调度,将高优先级任务优先处理。

通过使用容器适配器,可以简化代码的实现,提高开发效率。同时,由于容器适配器基于已有容器实现,性能和稳定性也得到了保证。

2.stack的介绍与使用

2.1介绍

stack是一种后进先出(LIFO,Last In First Out)的数据结构。它的特点是最后添加的元素最先被移除。stack适用于许多计算机科学领域和算法,包括递归、表达式求值、括号匹配、深度优先搜索(DFS)等。C++中的stack是通过容器适配器实现的,通常基于dequevector容器。

stack提供了一组特定的接口,包括:

  • push:将元素添加到栈顶。
  • pop:移除栈顶元素。
  • top:访问栈顶元素,但不移除它。
  • empty:检查栈是否为空。
  • size:获取栈中的元素数量。

这些接口使得stack可以方便地用于实现各种需要后进先出行为的算法和数据处理任务。

与直接使用dequevector不同,stack通过限制操作接口,确保了只能通过特定的方式访问和修改数据,从而保证了数据的后进先出顺序。这种封装和接口限制提高了代码的安全性和可读性,避免了不必要的操作干扰stack的逻辑。

2.2使用

stack容器适配器提供了一组简单但强大的操作接口,使得它能够高效地实现后进先出的数据管理。以下是stack的主要功能:

  • push:将元素添加到栈顶。每次调用push,新元素都会被放置在栈的顶部。
  • pop:移除栈顶元素。调用pop会删除位于栈顶的元素。注意,pop操作不会返回被移除的元素。
  • top:访问栈顶元素,但不移除它。top操作返回当前位于栈顶的元素,但不会改变栈的状态。
  • empty:检查栈是否为空。如果栈中没有元素,empty返回true,否则返回false
  • size:获取栈中的元素数量。size操作返回栈中当前元素的个数。

以下是一个使用stack的完整示例代码,展示了这些操作的实际使用:

#include <iostream>
#include <stack>int main() {std::stack<int> s;// 将元素添加到栈顶s.push(1);s.push(2);s.push(3);// 打印栈的大小std::cout << "Stack size: " << s.size() << std::endl;// 访问栈顶元素std::cout << "Top element: " << s.top() << std::endl;// 移除栈顶元素s.pop();// 再次访问栈顶元素std::cout << "Top element after pop: " << s.top() << std::endl;// 打印栈是否为空std::cout << "Is stack empty? " << (s.empty() ? "Yes" : "No") << std::endl;// 再次移除栈顶元素并打印状态s.pop();s.pop();std::cout << "Is stack empty after popping all elements? " << (s.empty() ? "Yes" : "No") << std::endl;return 0;
}

下面是以上代码的运行结果:

Stack size: 3
Top element: 3
Top element after pop: 2
Is stack empty? No
Is stack empty after popping all elements? Yes 

3.queue的介绍与使用

3.1介绍

queue是一种先进先出(FIFO,First In First Out)的数据结构。它的特点是最早添加的元素最先被移除。queue在很多应用场景中都非常实用,比如任务调度、缓冲区管理、广度优先搜索(BFS)等。C++中的queue是通过容器适配器实现的,通常基于dequelist容器。

queue提供了一组特定的接口,包括:

  • push:将元素添加到队列的末尾。
  • pop:移除队列的第一个元素。
  • front:访问队列的第一个元素,但不移除它。
  • back:访问队列的最后一个元素,但不移除它。
  • empty:检查队列是否为空。
  • size:获取队列中的元素数量。

这些接口使得queue可以方便地用于实现各种需要先进先出行为的算法和数据处理任务。

与直接使用dequelist不同,queue通过限制操作接口,确保了只能通过特定的方式访问和修改数据,从而保证了数据的先进先出顺序。这种封装和接口限制提高了代码的安全性和可读性,避免了不必要的操作干扰queue的逻辑。

3.2使用

queue容器适配器提供了一组简洁而强大的操作接口,使得它能够高效地实现先进先出的数据管理。以下是queue的主要功能:

  • push:将元素添加到队列的末尾。每次调用push,新元素都会被放置在队列的尾部。
  • pop:移除队列的第一个元素。调用pop会删除位于队列前端的元素。注意,pop操作不会返回被移除的元素。
  • front:访问队列的第一个元素,但不移除它。front操作返回当前位于队列前端的元素,但不会改变队列的状态。
  • back:访问队列的最后一个元素,但不移除它。back操作返回当前位于队列尾部的元素,但不会改变队列的状态。
  • empty:检查队列是否为空。如果队列中没有元素,empty返回true,否则返回false
  • size:获取队列中的元素数量。size操作返回队列中当前元素的个数。

以下是一个使用queue的完整示例代码,展示了这些操作的实际使用:

#include <iostream>
#include <queue>int main() {std::queue<int> q;// 将元素添加到队列末尾q.push(1);q.push(2);q.push(3);// 打印队列的大小std::cout << "Queue size: " << q.size() << std::endl;// 访问队列的第一个元素std::cout << "Front element: " << q.front() << std::endl;// 访问队列的最后一个元素std::cout << "Back element: " << q.back() << std::endl;// 移除队列的第一个元素q.pop();// 再次访问队列的第一个元素std::cout << "Front element after pop: " << q.front() << std::endl;// 打印队列是否为空std::cout << "Is queue empty? " << (q.empty() ? "Yes" : "No") << std::endl;// 再次移除队列的第一个元素并打印状态q.pop();q.pop();std::cout << "Is queue empty after popping all elements? " << (q.empty() ? "Yes" : "No") << std::endl;return 0;
}

 下面是以上代码的运行结果:

Queue size: 3
Front element: 1
Back element: 3
Front element after pop: 2
Is queue empty? No
Is queue empty after popping all elements? Yes

4.stack和queue的模拟实现

4.1 stack的模拟实现

下面是Stack类的模拟实现,它是一个模板类,使用一个底层容器Container(默认为deque)来实现栈的功能。我们将详细介绍其原理,并给出完整的代码和注释。

原理介绍

Stack类是一个容器适配器,它封装了一个底层容器Container,并通过限制其接口实现栈的后进先出(LIFO)行为。该类提供了基本的栈操作,包括pushpoptopsizeempty

  • push:将元素添加到栈顶。调用Containerpush_back方法实现。
  • pop:移除栈顶元素。调用Containerpop_back方法实现。
  • top:返回栈顶元素。调用Containerback方法实现。
  • size:返回栈中元素的数量。调用Containersize方法实现。
  • empty:检查栈是否为空。调用Containerempty方法实现。

以下是Stack类的完整代码和注释:

#pragma once
#include <deque>
#include <list>using namespace std;// 模板类Stack,默认使用deque作为底层容器
template<class T, class Container = deque<T>>
class Stack {
private:// 底层容器,用于存储栈的元素Container con;
public:// 默认构造函数Stack() {}// 将元素添加到栈顶void push(const T& val) {// 使用底层容器的push_back方法将元素添加到末尾con.push_back(val);}// 移除栈顶元素void pop() {// 使用底层容器的pop_back方法移除末尾元素con.pop_back();}// 返回栈顶元素T& top() {// 使用底层容器的back方法返回末尾元素return con.back();}// 返回栈中元素的数量size_t size() {// 使用底层容器的size方法获取元素数量return con.size();}// 检查栈是否为空bool empty() {// 使用底层容器的empty方法检查是否为空return con.empty();}
};

4.2 queue的模拟实现

下面是Queue类的模拟实现,它是一个模板类,使用一个底层容器Container(默认为deque)来实现队列的功能。我们将详细介绍其原理,并给出完整的代码和注释。

原理介绍

Queue类是一个容器适配器,它封装了一个底层容器Container,并通过限制其接口实现队列的先进先出(FIFO)行为。该类提供了基本的队列操作,包括pushpopfrontbacksizeempty

  • push:将元素添加到队列的末尾。调用Containerpush_back方法实现。
  • pop:移除队列的第一个元素。调用Containerpop_front方法实现。
  • front:返回队列的第一个元素。调用Containerfront方法实现。
  • back:返回队列的最后一个元素。调用Containerback方法实现。
  • size:返回队列中元素的数量。调用Containersize方法实现。
  • empty:检查队列是否为空。调用Containerempty方法实现。

以下是Queue类的完整代码和注释:

#pragma once
#include <list>
#include <deque>using namespace std;// 模板类Queue,默认使用deque作为底层容器
template<class T, class Container = deque<T>>
class Queue {
private:// 底层容器,用于存储队列的元素Container con;
public:// 默认构造函数Queue() {}// 将元素添加到队列末尾void push(const T& val) {// 使用底层容器的push_back方法将元素添加到末尾con.push_back(val);}// 移除队列的第一个元素void pop() {// 使用底层容器的pop_front方法移除第一个元素con.pop_front();}// 返回队列的第一个元素T& front() {// 使用底层容器的front方法返回第一个元素return con.front();}// 返回队列的最后一个元素T& back() {// 使用底层容器的back方法返回最后一个元素return con.back();}// 返回队列中元素的数量size_t size() {// 使用底层容器的size方法获取元素数量return con.size();}// 检查队列是否为空bool empty() {// 使用底层容器的empty方法检查是否为空return con.empty();}
};

5.结语

通过对C++标准模板库中的stackqueue的介绍与使用,我们深入了解了这两种重要的容器适配器。stackqueue在许多计算机科学领域和实际应用中都有广泛的使用场景。我们不仅学习了它们的基本操作和应用,还通过模拟实现进一步理解了其内部机制。掌握这些数据结构和容器适配器,将显著提升我们在算法设计和程序开发中的效率和能力。希望这篇博客能帮助读者更好地理解和应用stackqueue,为大家在编程道路上提供有力的支持。

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

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

相关文章

博客星球大冒险:用Spring Boot和JWT打造你的数字王国

揭秘如何在Spring Boot中无缝集成JWT&#xff0c;为你的应用打造一个高度可扩展且安全的认证系统。从添加依赖到创建JWT过滤器&#xff0c;再到实现令牌的有效性管理和刷新机制&#xff0c;每一步都精心设计&#xff0c;确保你的乐园能够迎接成千上万的游客&#xff01; 文章目…

LLM主流开源代表模型

LLM主流开源大模型介绍 1 LLM主流大模型类别 随着ChatGPT迅速火爆&#xff0c;引发了大模型的时代变革&#xff0c;国内外各大公司也快速跟进生成式AI市场&#xff0c;近百款大模型发布及应用。 目前&#xff0c;市面上已经开源了各种类型的大语言模型&#xff0c;本章节我们…

【MATLAB源码-第220期】基于matlab的Massive-MIMO误码率随着接收天线变化仿真采用ZF均衡和QPSK调制。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. 系统背景与目标 无线通信系统的发展极大地推动了现代通信技术的进步&#xff0c;从移动通信到无线局域网&#xff0c;甚至是物联网&#xff0c;均依赖于无线通信系统的高效和可靠性。在无线通信系统中&#xff0c;核心目…

【kafka】关于Kafka的入门介绍

为什么要使用kafka&#xff1f;kafka是什么东西&#xff1f; 案例场景 A服务向B服务发送消息&#xff0c;A服务传输数据很快&#xff0c;B服务处理数据很慢&#xff0c;这样B服务就会承受不住&#xff0c;怎么办&#xff1f;通过添加消息队列作为缓冲。kafka就是消息队列中的…

初识C++ · 模拟实现stack和Queue

目录 前言&#xff1a; 1 Stack 1.1 双端队列 2 Queue 前言&#xff1a; 经历了list三个自定义类型的洗礼&#xff0c;来个简单的放松放松&#xff0c;即栈和队列&#xff1a; 文档记录的&#xff0c;栈和队列是一种容器适配器&#xff0c;它们不属于stl&#xff0c;但是它…

低空经济发展报告

低空经济是指利用低空空间进行商业开发和经济活动的概念。随着航空技术的发展和无人机的普及&#xff0c;低空经济逐渐成为一个新兴的经济领域。 低空经济可以涵盖的领域非常广泛&#xff0c;包括但不限于物流配送、农业植保、城市交通、旅游观光等。利用无人机等飞行器进行物…

【算法】一文搞懂归并排序

概念 归并排序利用了分治思想&#xff0c;将待排序的数组范围层层划分&#xff0c;每次划分会得到两个大小相近的区间。当无法划分时&#xff0c;递归结束&#xff0c;自下而上进行区间合并merge操作&#xff0c;合并操作依次比较两个区间的元素&#xff0c;进而使合并后的区间…

【西瓜书】5.神经网络

1.概念 有监督学习正向传播&#xff1a;输入样本---输入层---各隐层---输出层反向传播&#xff1a;误差以某种形式在通过隐层向输入层逐层反转&#xff0c;并将误差分摊给各层的所有单元&#xff0c;以用于修正各层的权值激活函数&#xff1a;也叫阶跃函数&#xff0c;目的是引…

Maven 中的 classifier 属性用过没?

最近训练营有小伙伴问到松哥一个关于 Maven 依赖的问题&#xff0c;涉及到 classifier 属性&#xff0c;随机问了几个小伙伴&#xff0c;都说工作中没用到过&#xff0c;因此简单整篇文章和小伙伴们分享下。 Maven 大家日常开发应该都有使用&#xff0c;Maven 中有一个比较好玩…

最小二乘法算法(个人总结版)

最小二乘法&#xff08;Least Squares Method&#xff09;是一种通过最小化误差平方和来拟合数据的回归分析方法。它被广泛应用于线性回归、多元回归以及其他数据拟合问题中。以下是详细的教程&#xff0c;涵盖基本概念、数学推导、具体步骤和实现代码。 1. 最小二乘法基本概念…

装机必备——鲁大师安装教程

装机必备——鲁大师安装教程 软件下载 软件名称&#xff1a;鲁大师 软件语言&#xff1a;简体中文 软件大小&#xff1a;144.75M系统要求&#xff1a;Windows7或更高&#xff0c; 32/64位操作系统 硬件要求&#xff1a;CPU2GHz &#xff0c;RAM2G或更高 下载通道①迅雷云盘丨…

p5开发helloworld

注意&#xff0c;执行的时候&#xff0c;后面不用带class的后缀

C语言(字符、字符串函数)2

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#xff0c;在这里撰写成文一…

Pinia(三): 了解和使用state

1.state state 就是我们要定义的数据, 如果定义 store 时传入的第二个参数是对象, 那么 state 需要是一个函数, 这个函数的返回值才是状态的初始值.这样设计的原因是为了让 Pinia 在客户端和服务端都可以工作 官方推荐使用箭头函数(()>{ })获得更好的类型推断 import { de…

最新张量补全论文收集【8篇】

目录 1、利用张量子空间先验&#xff1a;增强张量补全的核范数最小化和 2、基于可学习空间光谱变换的张量核范数多维视觉数据恢复 3、用于图像补全的增强型低秩和稀疏 Tucker 分解 4、多模态核心张量分解及其在低秩张量补全中的应用 5、 低秩张量环的噪声张量补全 6、 视…

三十四、openlayers官网示例Dynamic clusters解析——动态的聚合图层

官网demo地址&#xff1a; https://openlayers.org/en/latest/examples/clusters-dynamic.html 这篇绘制了多个聚合图层。 先初始化地图 &#xff0c;设置了地图视角的边界extent&#xff0c;限制了地图缩放的范围 initMap() {const raster new TileLayer({source: new XYZ…

JAVA流程控制break,continue,goto

1.break在任何循环语句的主体成分&#xff0c;均可用break控制循环的流程。break用于强行退出循环&#xff0c;不执行循环中剩余的语句。&#xff08;break语句也在switch语句中使用&#xff09; 如图&#xff1a;break语句强行退出循环&#xff0c;结果输出1~30便结束&#xf…

两数之和-第13届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第76讲。 两数之和&#xf…

Java面试八股之死锁和活锁的区别

死锁和活锁的区别 基本定义&#xff1a; 死锁&#xff08;Deadlock&#xff09;&#xff1a;指两个或多个线程互相等待对方释放资源&#xff0c;从而导致所有线程都无法继续执行的状态。每个线程至少持有一个资源&#xff0c;并等待另一个由其他线程持有的资源&#xff0c;形…

初始操作系统

概念&#xff1a; 1.系统资源的管理者&#xff1a;实质控制和管理整个计算机系统的硬件和软件资源&#xff0c;并合理地组织调度计算机地工作和资源的分配 2.向上层提供方便易用的服务&#xff1a;以提供给用户和其他软件方便接口和环境 封装思想&#xff1a;操作系统把一些丑…