【C++初阶】第十一篇:stack和queue的使用与模拟实现

news2025/2/27 23:19:35

文章目录

  • stack和queue的介绍和使用
    • stack的介绍
      • stack的定义方式
      • stack的使用
    • queue的介绍
      • queue的定义方式
      • queue的使用
  • stack和queue的模拟实现
    • 容器适配器
    • stack的模拟实现
    • queue的模拟实现
  • 总结:

stack和queue的介绍和使用

stack的介绍

 stack的文档介绍

  1. stack是一种容器适配器,专门用于具有后进先出操作的上下文环境中,其只能从容器的一端进行元素的插入与提取操作。
    在这里插入图片描述
  2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。
  3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作:
    • empty:判空操作
    • back:获取尾部元素操作
    • push_back:尾部插入元素操作
    • pop_back:尾部删除元素操作
  4. 标准容器vector、deque、list均符合这些需求,默认情况下, 如果没有为stack指定特定的底层容器,默认情况下使用deque

stack的定义方式

方式一: 使用默认的适配器定义栈。

stack<int> st1;

方式二: 使用特定的适配器定义栈。

stack<int, vector<int>> st2;
stack<int, list<int>> st3;

注意: 如果没有为stack指定特定的底层容器,默认情况下使用deque。

stack的使用

stack当中常用的成员函数如下:

成员函数功能
empty判断栈是否为空
size获取栈中有效元素个数
top 获取栈顶元素
push 元素入栈
pop 元素出栈
swap 交换两个栈中的数据

示例:

#include <iostream>
#include <vector>
#include <stack>
using namespace std;

int main()
{
	stack<int, vector<int>> st;
	st.push(1);
	st.push(2);
	st.push(3);
	st.push(4);
	cout << st.size() << endl; //4
	while (!st.empty())
	{
		cout << st.top() << " ";
		st.pop();
	}
	cout << endl; //4 3 2 1
	return 0;
}

queue的介绍

 queue的文档介绍

  1. 队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素。
    在这里插入图片描述

  2. . 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。

  3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作:

    • empty:检测队列是否为空
    • size:返回队列中有效元素的个数
    • front:返回队头元素的引用
    • back:返回队尾元素的引用
    • push_back:在队列尾部入队列
    • pop_front:在队列头部出队列
  4. 标准容器类deque和list满足了这些要求。默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque。

queue的定义方式

方式一: 使用默认的适配器定义队列。

queue<int> q1;

方式二: 使用特定的适配器定义队列。

queue<int, vector<int>> q2;
queue<int, list<int>> q3;

注意: 如果没有为queue指定特定的底层容器,默认情况下使用deque。

queue的使用

queue当中常用的成员函数如下:

成员函数功能
empty判断队列是否为空
size获取队列中有效元素个数
front 获取队头元素
back 获取队尾元素
push 队尾入队列
pop 队头出队列
swap 交换两个队列中的数据

示例:

#include <iostream>
#include <list>
#include <queue>
using namespace std;

int main()
{
	queue<int> q;
	q.push(1);
	q.push(2);
	q.push(3);
	q.push(4);
	cout << q.size() << endl; //4
	while (!q.empty())
	{
		cout << q.front() << " ";
		q.pop();
	}
	cout << endl; //1 2 3 4
	return 0;
}

stack和queue的模拟实现

容器适配器

stack和queue有一点需要注意的是,虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stack和queue只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque容器。
在stack和queue的类模板声明当中我们就可以看到,它们的模板参数有两个,第一个是stack和queue当中所存储的元素类型,而另一个就是指定使用的容器类型。只不过当我们不指定使用何种容器的情况下,stack和queue都默认使用deque作为指定容器。
在这里插入图片描述

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

stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()和pop_back()操作的线性结构,都可以作为stack的底层容器,比如vector和list都可以;
queue是先进先出的特殊线性数据结构,只要具有push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如list。
但是STL中对stack和queue默认选择deque作为其底层容器,主要是因为:

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

结合了deque的优点,而完美的避开了其缺陷。

stack的模拟实现

知道了容器适配器后,stack的模拟实现就显得相当简单,我们只需要调用所指定容器的各个成员函数即可实现stack的各个函数接口

成员函数功能
empty判断栈是否为空
size获取栈中有效元素个数
top 获取栈顶元素
push 元素入栈
pop 元素出栈
swap 交换两个栈中的数据

实现代码如下:

#include<deque>
namespace wyt
{
    template<class T, class Container = deque<T>>
    class stack
    {
    public:
        stack()
        {}

		//元素入栈
        void push(const T& x)
        {
            _con.push_back(x);
        }
		//元素出栈
        void pop()
        {
            _con.pop_back();
        }
		//获取栈顶元素
        T& top()
        {
            return _con.back();
        }

        const T& top()const
        {
            return _con.back();
        }
		//获取栈中有效元素个数
        size_t size()const
        {
            return _con.size();
        }
		//判断栈是否为空
        bool empty()const
        {
            return _con.empty();
        }
		//交换两个栈中的数据
		void swap(stack<T, Container>& st)
		{
			_con.swap(st._con);
		}
    private:
        Container _con;
    };
}

queue的模拟实现

同样的方式,我们也是通过调用所指定容器的各个成员函数来实现queue的。

成员函数功能
empty判断队列是否为空
size获取队列中有效元素个数
front 获取队头元素
back 获取队尾元素
push 队尾入队列
pop 队头出队列
swap 交换两个队列中的数据

实现代码如下:

#include<deque>

namespace wyt
{
    template<class T, class Container = deque<T>>
    class queue
    {
    public:
        queue()
        {}
		//队尾入队列
        void push(const T& x)
        {
            _con.push_back(x);
        }
		//队头出队列
        void pop()
        {
            _con.pop_front();
        }
		//获取队尾元素
        T& back()
        {
            return _con.back();
        }

        const T& back()const
        {
            return _con.back();
        }
		//获取队头元素
        T& front()
        {
            return _con.front();
        }

        const T& front()const
        {
            return _con.front();
        }
		//获取队列中有效元素个数
        size_t size()const
        {
            return _con.size();
        }
		//判断队列是否为空
        bool empty()const
        {
            return _con.empty();
        }
		//交换两个队列中的数据
		void swap(queue<T, Container>& q)
		{
			_con.swap(q._con);
		}
    private:
        Container _con;
    };
}

总结:

以上就是stack和queue的使用和模拟实现,相对于前面学习的vector和list等的使用和实现简单许多。

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

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

相关文章

文本三剑客之~~~sed命令

目录 sed概念sed 的工作流程&#xff1a;命令格式&#xff1a;常用选项&#xff1a;常用操作&#xff1a; 示例&#xff1a;打印删除替换&#xff1a;插入&#xff1a;剪切复制将字符替换位置 sed概念 sed是一种流编辑器&#xff0c;流编辑器会在编辑器处理数据之前基于预先提…

Allegro加密PCB文件

写在前面&#xff1a; 记得以前不知道Allegro可以加密PCB文件的时候&#xff0c;就遇到了尴尬的事情。 其一&#xff1a;要发给别人layout文件&#xff0c;但是又怕别人外传&#xff0c;而且有关于公司文件保密的问题&#xff0c;其实这不论是公事还是私事&#xff0c;如果我…

软测人正在杀死软测行业

前言、一个软件做出来&#xff0c;最不能少的人是谁&#xff1f; 不用说就是开发&#xff0c;因为开发是最了解软件运作的那个人&#xff0c;早期不少一人撸网站或者APP的例子&#xff0c;相当于一个人同时是产品、研发、测试、运维等等&#xff0c;这也是为何开发是地位和上限…

如何一步一步构建网站ChatGPT插件

在本文中&#xff0c;我们将一步一步地探索并构建一个名为"AI Prompt Testing"的项目。该项目是一个网站插件&#xff0c;旨在帮助网站生成一个ChatGPT提示测试题&#xff0c;以巩固当前网页的内容。 1、抽象提取 这个网站ChatGPT插件大概的效果&#xff0c;类比的…

股票量价关系基础知识7----图解各阶段量价关系:价涨量缩

图解各阶段量价关系&#xff1a;价涨量缩 价涨量缩是指股价上涨&#xff0c;成交量却萎缩的一种价量背离走势。它通常反映上涨力道不足&#xff0c;预示股价可能反转向下。 一、上涨初期的价涨量缩 &#xff08;一&#xff09;形态分析 股价经过一轮下跌后止跌回升&#xff0c…

Redis中的缓存穿透、雪崩、击穿

概述&#xff1a; 缓存穿透&#xff1a;大量请求根本不存在的key&#xff0c; 应用服务器压力变大缓存雪崩&#xff1a;redis中大量key集体过期&#xff0c;数据库压力变大&#xff0c;服务器崩溃缓存击穿&#xff1a;redis中一个热点key过期&#xff08;大量用户访问该热点ke…

【Linux】驱动学习,先啃框架

目录 前言&#xff1a; 一、驱动设计 &#xff08;1&#xff09;面向对象&#xff1a; &#xff08;2&#xff09;分层&#xff1a; &#xff08;3&#xff09;分离&#xff1a; 二、驱动框架 &#xff08;1&#xff09;传统框架 &#xff08;2&#xff09;总线设备驱…

四.从零开始JVM实战高手-JVM监控及线上问题定位

前言 Java程序员面试JVM几乎比问&#xff0c;对于JVM监控&#xff0c;线上OOM&#xff0c;CPU负载100%等问题也是经常被问到&#xff0c;尽管在企业中不一定轮得到我们去处理线上问题&#xff0c;但是不管是为了面试还是为了应对开发那么对于JVM线上问题处理都是必须要去了解的…

二、软件工程——Modeling

1.Undestanding Requirements System Engineering&#xff08;系统工程&#xff09; &#xff01;&#xff01;&#xff01;Requirements Engieering(需求建模&#xff09; 1.Inception&#xff08;开始&#xff09;&#xff1a;&#xff08;确认利益相关者&#xff09; 2.…

164道网络安全工程师面试题(附答案)

为了更好地帮助大家高薪就业&#xff0c;今天就给大家分享两份网络安全工程师面试题&#xff0c;一共有164道面试真题&#xff0c;希望它们能够帮助大家在面试中&#xff0c;少走一些弯路、更快拿到offer&#xff01; 93道网络安全面试题 1、什么是SQL注入攻击 2、什么是XSS…

Linux中的特殊进程:idle进程(0号进程)、init进程(1号进程,被systemd 取代 )、kthreadd进程(2号进程)

文章目录 1. Linux中的三个特殊进程&#xff1a;2. idle进程、init进程、kthreadd进程的创建3 kthreadd进程3.1 kthreadd进程的启动3.2 kthreadd进程创建子进程3.3 kthreadd的工作流程总结 4. init进程4.1 init进程的启动 4. 总结参考 1. Linux中的三个特殊进程&#xff1a; i…

【作者踩坑总结0错版】vscode配置codeql-MacBook(M1/M2芯片-arm)

文章目录 前言一、codeql是什么二、安装必备工具2.1、安装codeql-cli2.2、安装codeql仓库2.3、桌面新建文件夹2.4、安装vscode 三、配置codeql环境变量四、vscode配置codeql插件4.1、下载测试靶场4.2、生成数据库文件&#xff08;最难最多bug&#xff09;4.3、vscode配置ql数据…

[入门必看]数据结构5.3:二叉树的遍历和线索二叉树

[入门必看]数据结构5.3&#xff1a;二叉树的遍历和线索二叉树 第五章 树与二叉树5.3 二叉树的遍历和线索二叉树知识总览5.3.1_1 二叉树的先中后序遍历5.3.1_2 二叉树的层次遍历5.3.1_3 由遍历序列构造二叉树5.3.2_1 线索二叉树的概念5.3.2_2 二叉树的线索化5.3.2_3 在线索二叉树…

服务(第十九篇)mysql的备份和恢复

备份的类型&#xff1a; ①物理备份&#xff1a;备份数据库的物理文件&#xff0c;数据文件和日志文件&#xff1b; 冷备份&#xff1a;关闭数据库进行的&#xff1b; 热备份&#xff1a;数据库处于运行中状态&#xff0c;依赖于日志文件&#xff1b; 温备份&#xff1a;数…

Cisco NX-OS Software Release 10.3(3)F - 网络操作系统软件

Cisco NX-OS Software Release 10.3(3)F - 网络操作系统软件 请访问原文链接&#xff1a;https://sysin.org/blog/cisco-nx-os-10/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Cisco NX-OS Cisco NX-OS 操作系统助力网络紧…

Golang中map基础

目录 map类型 声明和初始化 元素操作 大小和容量 并发问题 实现原理 注意 map类型 Go语言中的map类型是一种key-value&#xff08;键值对&#xff09;结构&#xff0c;用于存储一组无序的数据&#xff0c;其中键是唯一的&#xff0c;值可以相同或者不同。在Go语言的程序…

button 设置外观

导入图片 设置拉伸 设置按钮的FlatStyle属性为Flat 设置透明背景

先到先得先学,2023最新国内大厂最新Java面试八股文总结

“铜三铁四”接近尾声&#xff0c;身边被迫“毕业”或者主动在这个时间点跳槽的大佬基本该找到工作的都找到工作了&#xff0c;找不到的也大多数都已经躺平了&#xff08;手动狗头&#xff09;&#xff0c;只剩一群“45度人”&#xff08;卷不动&#xff0c;躺不平的人&#xf…

用于跨中心多边形分割的任务相关特征补充

文章目录 Task-Relevant Feature Replenishment for Cross-Centre Polyp Segmentation摘要本文方法Domain-Invariant Feature Decomposition (DIFD)Task-Relevant Feature ReplenishmentPolyp-Aware Adversarial Learning (PAAL)总损失函数 结果 Task-Relevant Feature Repleni…

AI翻译工具分享

LanguageX简介 冠军翻译引擎交互式翻译,为专业译者而生的新一代译者工具 自2017年神经网络机器翻译流行以来,“机器翻译替代人工翻译”的观点屡见不鲜。作为一个技术和语言背景结合的团队,LanguageX认为语言服务是高度复杂、需要创意的智力活动,并肩负着人类沟通的重要使命。La…