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.mfbz.cn/a/676326.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

探秘IPv6协议在车载网络的应用:打造智能出行新体验

绪论 1969年&#xff0c;互联网的前身——ARPANET成功地连接了四个关键节点&#xff1a;①加州大学洛杉矶分校、②斯坦福研究所、③加州大学圣巴巴拉分校、④犹他州大学。这四个节点的成功连接标志着分组交换&#xff08;Packet Switching&#xff09;网络的正式运行&#xff…

SpringBoot登录认证--衔接SpringBoot案例通关版

文章目录 登录认证登录校验-概述登录校验 会话技术什么是会话呢?cookie Session令牌技术登录认证-登录校验-JWT令牌-介绍JWT SpringBoot案例通关版,上接这篇 登录认证 先讲解基本的登录功能 登录功能本质就是查询操作 那么查询完毕后返回一个Emp对象 如果Emp对象不为空,那…

Android期末大作业:使用AndroidStudio开发图书管理系统APP(使用sqlite数据库)

Android Studio开发项目图书管理系统项目视频展示&#xff1a; 点击进入图书管理系统项目视频 引 言 现在是一个信息高度发达的时代&#xff0c;伴随着科技的进步&#xff0c;文化的汲取&#xff0c;人们对于图书信息的了解与掌握也达到了一定的高度。尤其是学生对于知识的渴…

wvp-gb28181-pro搭建流媒体服务器,内存占用过高问题

直接给出解决办法,端口暴露的太多了,暴露了500个端口导致从3g---->11g 遇到的问题,直接使用镜像《648540858/wvp_pro:latest》在宿主机上运行,如我下面的博客 https://blog.csdn.net/weixin_41012767/article/details/137112338?spm=1001.2014.3001.5502 docker run …

ChineseChess.2024.06.03

ChineseChess.2024.06.03 中国象棋&#xff0c;我下得不是象棋&#xff0c;是娱乐&#xff0c;是想看看自己的程序。哈哈 看很多主播挂棋局&#xff0c;吹牛批&#xff0c;为了涨粉&#xff0c;挂着&#xff0c;蛮摆个残局 中国象棋残局模拟器ChineseChess.2024.06.03

HTML:认识HTML与基本语法的学习

前言 HTML&#xff08;超文本标记语言&#xff09;是用于创建网页的标记语言&#xff0c;由一系列标签组成&#xff0c;定义网页中的元素。由蒂姆伯纳斯 - 李于1990年代初发明&#xff0c;最初用于科研机构间共享文档&#xff0c;迅速演变为Web开发基础。无论是电商、博客、新…

攻防世界---misc---reverseMe

1、这道题是做过最简单的misc题&#xff0c;下载附件是一个图片 2、flag是反的&#xff0c;但是可以自己倒着推也能写出 3、这里推荐使用工具&#xff0c;双击图片&#xff0c;它打开是用的系统自带的软件打开 点击这里最图片编辑 4、接着点击矫正 5、点击这个左右翻转 6、得…

64位Office API声明语句第119讲

跟我学VBA&#xff0c;我这里专注VBA, 授人以渔。我98年开始&#xff0c;从源码接触VBA已经20余年了&#xff0c;随着年龄的增长&#xff0c;越来越觉得有必要把这项技能传递给需要这项技术的职场人员。希望职场和数据打交道的朋友&#xff0c;都来学习VBA,利用VBA,起码可以提高…

我们如何管理网站权限?这么操作最简单

网站权限有哪些 在知道如何管理网站权限之前我们先来了解一下网站权限都有哪些。在日常我们使用浏览器的时候网站都会使用你同意的某些权限进行一些操作&#xff0c;下面是总结的一些网站权限&#xff1a; 位置访问权限&#xff1a;控制网站是否可以访问你的地理位置数据。 …

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

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

详解和实现数据表格中的行数据合并功能

theme: smartblue 前言 需求场景&#xff1a; 在提供了数据查看和修改的表格视图中(如table、a-table等…)&#xff0c;允许用户自行选择多行数据&#xff0c;依据当前状态进行特定列数据的合并操作。选中的数据将统一显示为选中组的首条数据值。同时&#xff0c;页面会即时反…

k8s怎么监听资源的变更

监听k8s所有的 Deployment 资源 package mainimport ("context""fmt"v1 "k8s.io/api/apps/v1""k8s.io/apimachinery/pkg/util/json""k8s.io/client-go/informers""k8s.io/client-go/kubernetes""k8s.io/cli…

linux,lseek,append用法

打开写的.c文件 内容为 代码 <sys/stat.h> #include <fcntl.h> #include<stdio.h> #include<unistd.h> #include<string.h>//off_t lseek(int fd, off_t offset, int whence); //int open(const char *pathname, int flags); //int open(const …

一个AI板卡电脑--香橙派 AIpro

本文算是一个开箱测评&#xff0c;主要评估它和一个电脑的距离。 香橙派官网&#xff1a;香橙派(Orange Pi)-Orange Pi官网-香橙派开发板,开源硬件,开源软件,开源芯片,电脑键盘香橙派&#xff08;Orange Pi&#xff09;是深圳市迅龙软件有限公司旗下开源产品品牌;香橙派&#x…

【触想智能】工业平板电脑在高铁上的应用分析

随着科技的快速发展&#xff0c;平板电脑作为一种新型的电子设备&#xff0c;已经逐渐成为人们日常生活中的必需品。而工业平板电脑则是一种更为专业的平板电脑&#xff0c;可以应用于各种工业领域&#xff0c;如交通、制造业、医疗、金融、人工智能等。 今天&#xff0c;小编为…

Oracle Hint /*+APPEND*/插入性能总结

oracle append用法 Oracle中的APPEND用法主要用于提高数据插入的效率。 基本用法&#xff1a;在使用了APPEND选项后&#xff0c;插入数据会直接加到表的最后面&#xff0c;而不会在表的空闲块中插入数据。这种做法不需要寻找freelist中的free block&#xff0c;从而避免了在…

推荐一个图片识别的llama3微调版本 清华面壁项目

水一篇&#xff1a; MiniCPM-V是面向图文理解的端侧多模态大模型系列。该系列模型接受图像和文本输入&#xff0c;并提供高质量的文本输出。自2024年2月以来&#xff0c;我们共发布了4个版本模型&#xff0c;旨在实现领先的性能和高效的部署&#xff0c;目前该系列最值得关注的…

36【Aseprite 作图】蒸笼盖——拆解

1 蒸笼盖框架 里圈和外圈的形状都是一样的 扶手处&#xff0c;2 1 2 2 2&#xff08;最好都是2&#xff0c;拐角处用1&#xff09; 2 上色 中间的波浪&#xff0c;是2 2 2 上&#xff08;再 2 2 2 下&#xff09; 下方阴影&#xff0c;左边的阴影&#xff0c;右边的阴影颜色…

【Elasticsearch】es基础入门-02.RestClient操作索引库

RestClient操作索引库 示例&#xff1a; 一.分析数据结构&#xff0c;写索引库 #酒店的mapper PUT /hotel {"mappings": {"properties": {"id":{"type": "keyword"},"name":{"type": "text",…

p5开发helloworld

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