当前位置: 首页 > news >正文

C++ 核心数据结构:Stack 与 Queue 类深度解析

 🌟快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。 🌟    


目录

💯前言

💯Stack 类

(一)Stack 类的概念与特点

(二)Stack 类的使用

(三)Stack 类的内部实现(手动实现)

(四)Stack 类的应用场景

💯Queue 类

(一)Queue 类的概念与特点

(二)Queue 类的使用

(三)Queue 类的内部实现(手动实现)

(四)Queue 类的应用场景

💯总结


💯前言

在 C++ 编程领域,数据结构的合理运用是构建高效、可靠程序的关键因素之一。Stack(栈)和 Queue(队列)作为两种基础且重要的数据结构,在众多编程场景中发挥着不可或缺的作用。深入理解它们的原理、特性、操作方式以及内部实现机制,对于提升编程技能、优化程序性能以及解决复杂问题具有深远意义。

接下来,我们将详细解析 Stack 类和 Queue 类,并手动实现它们,以深入探究其内部奥秘。

 


💯Stack 类

(一)Stack 类的概念与特点

  1. 后进先出(LIFO)原则

    Stack 类遵循后进先出的规则,类似于一叠盘子,最后放置的盘子最先被取出。这种特性使得 Stack 在处理具有嵌套结构或需要回溯的问题时表现出色。例如,在函数调用过程中,每次函数调用时的局部变量、参数等信息会依次压入栈中,当函数返回时,这些信息按照后进先出的顺序依次弹出,从而恢复到调用前的状态。

  2. 操作受限性

    Stack 类主要提供了入栈(push)、出栈(pop)、获取栈顶元素(top)、判断栈是否为空(empty)和获取栈的大小(size)等操作。与其他数据结构相比,其操作相对简单且受限,但这也使得它在特定场景下的使用更加高效和便捷。例如,在表达式求值中,我们只需关注当前操作符和操作数,通过栈来存储和处理它们,避免了复杂的遍历和搜索操作。

 

(二)Stack 类的使用

1.包含头文件与创建对象

要使用 Stack 类,需包含<stack>头文件(在我们手动实现的示例中暂不涉及该头文件)。然后可以通过以下方式创建一个 Stack 对象(在手动实现部分会有不同的创建方式):

#include <iostream>
#include <stack>
using namespace std;int main() {stack<int> myStack;// 后续操作...return 0;
}

2.基本操作示例

  • 入栈操作(push):将元素压入栈顶。
myStack.push(10);
myStack.push(20);
myStack.push(30);
  • 出栈操作(pop):弹出栈顶元素。
myStack.pop();
  • 获取栈顶元素(top):返回栈顶元素的值,但不弹出元素。
cout << "栈顶元素: " << myStack.top() << endl;
  • 判断栈是否为空(empty):如果栈为空,返回true,否则返回false
if (myStack.empty()) {cout << "栈为空" << endl;
} else {cout << "栈不为空" << endl;
}
  • 获取栈的大小(size):返回栈中元素的数量。
cout << "栈的大小: " << myStack.size() << endl;

 

 

(三)Stack 类的内部实现(手动实现)

  1. 数据结构选择
    为了手动实现 Stack 类,我们可以选择使用数组或链表来存储元素。这里我们以数组为例进行实现。
  2. 类定义与成员变量
    template<typename T>
    class MyStack {
    private:T* data;int topIndex;int capacity;public:// 构造函数MyStack() {capacity = 10;data = new T[capacity];topIndex = -1;}// 析构函数~MyStack() {delete[] data;}

  3. 入栈操作(push)实现
    void push(const T& value) {if (topIndex == capacity - 1) {// 栈已满,需要扩容capacity *= 2;T* newData = new T[capacity];for (int i = 0; i <= topIndex; i++) {newData[i] = data[i];}delete[] data;data = newData;}topIndex++;data[topIndex] = value;
    }

  4. 出栈操作(pop)实现
    void pop() {if (topIndex >= 0) {topIndex--;}
    }

  5. 获取栈顶元素(top)实现
    T& top() {return data[topIndex];
    }

  6. 判断栈是否为空(empty)实现
    bool empty() const {return topIndex == -1;
    }

  7. 获取栈的大小(size)实现
        int size() const {return topIndex + 1;}
    };

 

(四)Stack 类的应用场景

  1. 函数调用栈
    • 在程序执行过程中,函数的调用和返回顺序通过栈来管理。每当一个函数被调用时,系统会为其分配一个栈帧,用于存储函数的局部变量、参数、返回地址等信息。🚩当函数执行完毕返回时,栈帧被弹出,恢复之前的执行环境。这种机制保证了函数调用的嵌套和递归能够正确执行。
  2. 表达式求值
    • 对于中缀表达式的求值,通常需要将其转换为后缀表达式,然后利用栈来计算。在计算后缀表达式时,操作数依次入栈,遇到运算符时弹出栈顶的操作数进行计算,并将结果再次压入栈中。最终栈顶元素即为表达式的值。
  3. 括号匹配检查
    • 在处理包含括号的表达式或代码结构时,栈可用于检查括号是否匹配。例如,在编译器中,用于检查代码中的括号是否成对出现,🚩通过将左括号入栈,遇到右括号时与栈顶左括号匹配,若匹配成功则弹出栈顶左括号,否则表示括号不匹配。

💯Queue 类

(一)Queue 类的概念与特点

  1. 先进先出(FIFO)原则

    Queue 类遵循先进先出的规则,就像人们在排队等候,最先进入队列的元素最先被取出。这种特性使得 Queue 在处理需要按照顺序处理的任务或数据时非常有用。例如,在任务调度系统中,任务按照提交的顺序依次进入队列,然后按照先进先出的顺序被执行,保证了任务处理的公平性和顺序性。

  2. 操作特性

    Queue 类主要提供了入队(enqueue)、出队(dequeue)、获取队首元素(front)、判断队列是否为空(empty)和获取队列的大小(size)等操作。它专注于在队尾添加元素和在队首删除元素,确保了元素的顺序性。例如,在广度优先搜索算法中,队列用于存储待访问的节点,按照先进先出的顺序依次访问节点,从而实现对图或树的广度优先遍历。

(二)Queue 类的使用

  1. 包含头文件与创建对象
    要使用 Queue 类,需包含<queue>头文件(在手动实现示例中暂不涉及)。然后可以通过以下方式创建一个 Queue 对象(手动实现部分会有不同创建方式):
    #include <iostream>
    #include <queue>
    using namespace std;int main() {queue<int> myQueue;// 后续操作...return 0;
    }

  2. 基本操作示例
  • 入队操作(enqueue):将元素添加到队尾。
    myQueue.push(10);
    myQueue.push(20);
    myQueue.push(30);

  • 出队操作(dequeue):删除队首元素。
    myQueue.pop();

  • 获取队首元素(front):返回队首元素的值,但不删除元素。
    cout << "队首元素: " << myQueue.front() << endl;

  • 判断队列是否为空(empty):如果队列为空,返回true,否则返回false
    if (myQueue.empty()) {cout << "队列为空" << endl;
    } else {cout << "队列不为空" << endl;
    }

  • 获取队列的大小(size):返回队列中元素的数量。
    cout << "队列的大小: " << myQueue.size() << endl;

 

(三)Queue 类的内部实现(手动实现)

  1. 数据结构选择
    同样,我们可以使用数组或链表来手动实现 Queue 类。这里我们以链表为例进行实现。
  2. 类定义与节点结构体
    template<typename T>
    class MyQueue {
    private:struct Node {T data;Node* next;Node(const T& value) : data(value), next(nullptr) {}};Node* frontNode;Node* rearNode;int size;public:// 构造函数MyQueue() : frontNode(nullptr), rearNode(nullptr), size(0) {}// 析构函数~MyQueue() {while (frontNode) {Node* next = frontNode->next;delete frontNode;frontNode = next;}}

  3. 入队操作(enqueue)实现
    void push(const T& value) {Node* newNode = new Node(value);if (rearNode) {rearNode->next = newNode;} else {frontNode = newNode;}rearNode = newNode;size++;
    }

  4. 出队操作(dequeue)实现
    void pop() {if (frontNode) {Node* next = frontNode->next;delete frontNode;frontNode = next;if (!frontNode) {rearNode = nullptr;}size--;}
    }

  5. 获取队首元素(front)实现
    T& front() {return frontNode->data;
    }

  6. 判断队列是否为空(empty)实现
    bool empty() const {return size == 0;
    }

  7. 获取队列的大小(size)实现
        int size() const {return size;}
    };

 

(四)Queue 类的应用场景

  1. 任务调度
    • 在操作系统或任务管理系统中,任务通常按照提交的顺序依次进入队列,然后由处理器按照先进先出的顺序从队列中取出任务进行执行。这种方式确保了任务的公平处理,避免了某些任务长时间等待而得不到执行的情况。
  2. 广度优先搜索(BFS)算法
    • 在对图或树进行广度优先搜索时,队列用于存储待访问的节点。🚩从起始节点开始,将其相邻节点依次入队,然后按照先进先出的顺序取出节点进行访问,并将访问过的节点标记。接着将已访问节点的未访问相邻节点入队,重复这个过程,直到队列为空或找到目标节点。通过队列的先进先出特性,实现了对图或树的层次遍历。
  3. 消息队列
    • 在分布式系统或异步编程中,消息队列用于存储和传递消息。消息按照发送的顺序依次进入队列,接收方按照先进先出的顺序从队列中获取消息进行处理。🚩这种方式保证了消息处理的顺序性,避免了消息乱序导致的问题。

💯总结

✍Stack 类和 Queue 类是 C++ 编程中极为重要的数据结构,它们各自独特的特性和操作方式使其在不同编程场景中发挥着关键作用。通过深入理解它们的概念、使用方法、内部实现机制(尤其是手动实现过程)以及应用场景,我们能够在编程时更加灵活地运用它们解决复杂问题,提高程序效率和可读性。在实际编程中,应根据具体需求选择合适的数据结构,充分发挥其优势,构建高效、健壮的程序。同时,深入了解其底层实现原理有助于在遇到性能瓶颈或特殊需求时对程序进行优化和定制。🍎希望本文能帮助读者更好地掌握 Stack 类和 Queue 类,助力 C++ 编程之旅。


 觉得本文有用?欢迎关注我呀,更多编程干货持续分享哦。

👉【A Charmer】 

相关文章:

C++ 核心数据结构:Stack 与 Queue 类深度解析

&#x1f31f;快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f31f; 目录 &#x1f4af;前言 &#x1f4af;Stack 类 &#xff08;一&#xff09;Stack 类的概念与特点 &#xff08;二&#x…...

Python枚举类详解:用enum模块高效管理常量数据

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 在编程中,常量的管理是一个关键环节,合理的管理常量可以提高代码的可读性和可维护性。Python的enum模块提供了一种有效的方式来组织常量数据,通过枚举类(Enum)将相关的常量值集合在一起,使代码更具结…...

企业OA管理系统:Spring Boot技术深度探索

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…...

汽车免拆诊断案例 | 2012款路虎揽胜运动版柴油车加速无力

故障现象  一辆2012款路虎揽胜运动版车&#xff0c;搭载3.0T柴油发动机&#xff08;型号为306DT&#xff09;&#xff0c;累计行驶里程约为10.2万km。车主进厂反映&#xff0c;车辆行驶中加速无力&#xff0c;且发动机故障灯异常点亮。 故障诊断 接车后试车&#xff0c;发动…...

uniapp接入高德地图

下面代码兼容安卓APP和H5 高德地图官网&#xff1a;我的应用 | 高德控制台 &#xff0c;绑定服务选择《Web端(JS API)》 /utils/map.js 需要设置你自己的key和安全密钥 export function myAMap() {return new Promise(function(resolve, reject) {if (typeof window.onLoadM…...

(UI自动化测试)web自动化测试

web自动化测试 UI自动化测试介绍 自动化测试理论&#xff1a; 图片上的文字等等不能做测试&#xff0c;只能发现固定的bug 工具选择及介绍 浏览器驱动&#xff1a;找元素--核心&#xff1a;驱动&#xff08;操作元素&#xff09;--通过代码...

【es6进阶】如何使用Proxy实现自己的观察者模式

观察者模式&#xff08;Observer mode&#xff09;指的是函数自动观察数据对象&#xff0c;一旦对象有变化&#xff0c;函数就会自动执行。这里&#xff0c;我们是使用es6的proxy及reflect来实现这个效果。 实现效果 业务分析 源数据 const object2 {name: "张三"…...

住宅IP怎么在指纹浏览器设置运营矩阵账号

矩阵账号的运营已经成为了许多企业和个人推广策略中的重要一环。通过构建和管理多个社交媒体或电商平台的账号&#xff0c;可以有效地扩大品牌影响力&#xff0c;提高市场覆盖率。然而&#xff0c;随着平台对账号关联的限制越来越严格&#xff0c;如何安全、有效地运营这些矩阵…...

表格数据处理中大语言模型的微调优化策略研究

论文地址 Research on Fine-Tuning Optimization Strategies for Large Language Models in Tabular Data Processing 论文主要内容 这篇论文的主要内容是研究大型语言模型&#xff08;LLMs&#xff09;在处理表格数据时的微调优化策略。具体来说&#xff0c;论文探讨了以下…...

CentOS7 如何查看kafka topic中的数据

1. 确保 Kafka 服务运行 先检查 Kafka 和 Zookeeper 是否正在运行&#xff1a; systemctl status kafka systemctl status zookeeper 如果没有启动&#xff0c;先启动服务&#xff1a; systemctl start zookeeper systemctl start kafka 2. 进入 Kafka 安装目录 通常 …...

VRRP实现出口网关设备冗余备份

VRRP虚拟路由冗余 vrrp实现设备主备备份 Tips&#xff1a; VRRP能够在不改变组网的情况下&#xff0c;将多台路由器虚拟成一个虚拟路由器&#xff0c;通过配置虚拟路由器的IP地址为默认网关&#xff0c;实现网关的备份。协议版本: VRRPV2 (常用)和VRRPV3:VRRPV2仅适用于IPv4…...

超详细:Redis分布式锁

如何基于 Redis 实现一个最简易的分布式锁&#xff1f; 不论是本地锁还是分布式锁&#xff0c;核心都在于“互斥”。 在 Redis 中&#xff0c; SETNX 命令是可以帮助我们实现互斥。SETNX 即 SET if Not eXists (对应 Java 中的 setIfAbsent 方法)&#xff0c;如果 key 不存在…...

Vue与React的Suspense组件对比

在Vue和React中都内置了Suspense组件&#xff0c;该组件用于处理异步组件加载。当Suspense包裹的实际组件内容尚未加载完成时会先展示后备内容&#xff0c;等待组件内容加载完成后再切换成实际组件内容。这可以显著提升用户体验&#xff0c;适用于大数据加载、组件懒加载等场景…...

Spring框架深度剖析:特性、安全与优化

文章目录 Spring框架简介主要特性1. 依赖注入&#xff08;Dependency Injection, DI&#xff09;2. 面向切面编程&#xff08;Aspect-Oriented Programming, AOP&#xff09;3. 声明式事务管理4. 强大的MVC框架5. 集成测试支持6. 多种数据访问技术的支持 安全性1. 认证&#xf…...

硬盘文件误删:全面解析、恢复方案与预防策略

一、硬盘文件误删现象概述 在日常使用电脑的过程中&#xff0c;硬盘文件误删是许多用户都曾遇到过的问题。这种意外的数据丢失&#xff0c;不仅可能让我们辛苦编辑的文档、珍贵的照片和视频等瞬间消失&#xff0c;还可能对工作和生活造成重大影响。硬盘文件误删&#xff0c;如…...

tcpdump抓包 wireShark

TCPdump抓包工具介绍 TCPdump&#xff0c;全称dump the traffic on anetwork&#xff0c;是一个运行在linux平台可以根据使用者需求对网络上传输的数据包进行捕获的抓包工具。 tcpdump可以支持的功能: 1、在Linux平台将网络中传输的数据包全部捕获过来进行分析 2、支持网络层…...

Android system_server进程

目录 一、system_server进程介绍 二、system_server进程启动流程 2.1 startBootstrapServices 2.2 startCoreServices 2.3 startOtherServices 2.4 startApexServices 三、如何使用系统服务 3.1 app进程调用系统服务 3.2 native进程调用系统服务 3.3 system_server进…...

Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)

1、前言 在 Vue 3 项目中结合 vue-i18n 和 Element Plus 实现中英文切换是一个常见的需求。下面是一个详细的步骤指南&#xff0c;帮助你完成这个任务。 安装引入 1. 安装依赖 首先&#xff0c;你需要安装 vue-i18n 和 Element Plus。 npm install vue-i18nnext element-p…...

python实现猜数字游戏( 可视化easygui窗口版本 )

1.先上源代码 import random import easygui as egdef guess_ordinary():answer random.randint(0, 11)user_answer int(eg.enterbox(msg "请在0-10中选择一个整数: ", title "猜数字"))if user_answer answer:eg.msgbox(msg "恭喜你&#xff…...

自由学习记录(23)

Lua的学习 table.concat(tb,";") 如果表里带表&#xff0c;则不能拼接&#xff0c;表里带nil也不能&#xff0c;都会报错 true和false也不可以&#xff0c;数字和字符串可以 if要和一个end配对&#xff0c;所以 if a>b then return true end end 两个end …...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...