C嘎嘎探索篇:栈与队列的交响:C++中的结构艺术

C嘎嘎探索篇:栈与队列的交响:C++中的结构艺术

前言:

小编在之前刚完成了C++中栈和队列(stack和queue)的讲解,忘记的小伙伴可以去我上一篇文章看一眼的,今天小编将会带领大家吹奏栈和队列的交响,完成对于他们的模拟实现,使各位更容器去了解它们为什么被叫做容器适配器。
在这里插入图片描述

文章目录

  • C嘎嘎探索篇:栈与队列的交响:C++中的结构艺术
    • 1.stack的模拟实现
      • 1.1.stack类初步书写
      • 1.2.入栈函数push()的实现
      • 1.3.出栈函数pop()的模拟实现
      • 1.4.判空函数empty()的模拟实现
      • 1.5.个数函数size()的模拟实现
      • 1.6.栈顶函数top()的模拟实现
    • 2.小警示
    • 3.queue的模拟实现
      • 3.1.queue类的初步实现
      • 3.2.入队列函数push()的模拟实现
      • 3.3.出队列函数pop()的模拟实现
      • 3.4.取队头函数front()的模拟实现
      • 3.5.取队尾函数back()的模拟实现
      • 3.6.判空函数empty()的模拟实现
      • 3.7.个数函数size()的模拟实现
    • 4.代码展示
      • 4.1.stack
      • 4.2.queue
    • 5.总结

正文:

1.stack的模拟实现

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先我们就要先实现stack的模拟实现,栈我们以前在数据结构阶段是用顺序表进行实现的,小编此时也是要用一个容器来对其进行实现的,我们在它的众多接口中,不难发现stack是和vector是很像的,所以我们想要实现出stack,就是要给予vector容器进行模拟实现的,当然通过上图我们知道系统是用双端队列(deque)进行实现的,但是比其它,我还是更喜欢使用vector进行模拟实现,小编建议读者朋友在看我模拟实现之前,倘若不了解vector是如何进行使用的,可以先看我之前写过的文章来回顾一下(我先不放上链接了,因为在我写本文之前我还没有发布那篇文章),因为等会我会使用vector的一些接口来帮助我实现出stack,下面开始进入stack类的模拟实现。

1.1.stack类初步书写

我们首先需要先把我们自己写的stack定义在一个命名空间里面,避免和std命名空间里面的stack起冲突,因为stack是一个模版类,所以我们应该用模版类的方式来书写这个类,里面的参数我们对照着标准库书写即可,在我们写完外层以后,就是要书写内层了,此时我们先定一个成员变量,它的类型自然就是Container类型(这个类型可以是vector,可以是list,甚至是string),这个成员变量是为了后续数据的增删而写,下面小编给出这部分代码的书写:

namespace wang   //保存在命名空间里面,避免出现名字冲突,防患于未然
{template<class T,class Container = std :: vector<T>>  //默认使用的容器是vector,也可以是list,毕竟也有链式栈的存在class stack{private:Container s1;  //s1是为了保存数据的,增删还是需要靠它。};
}

1.2.入栈函数push()的实现

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可能到这里可能很多读者朋友会疑惑我为什么没有书写stack的构造函数,对于对此有疑惑的读者朋友,请好好的去复习一下类和对象的知识,还记着类和对象知识的读者朋友都知道,对于自定义类型的成员变量,编译器是会自己去调用它的构造函数的,如果成员变量没有构造函数的,那么编译器会直接报错,自定义类型需要自己写,当然不写的话系统会调用默认构造函数(默认构造函数有三种,这只是特殊情况之一),所以各位记住这一点,此时s1是vector类型的,它是会自己去调用自己的构造函数的,我们不用瞎操心,下面我们正式堆push()的实现进行讲述。

其实push()函数的实现,我们仅需去复用s1中的接口即可,看看上图stack的构造,我们不难发现此时我们仅需在一个vector类型的尾部插入数据即可,此时我们就可以去调用vector当中的尾插函数即可,根本不用我们自己思考了,所以这就是我前面说stack很好实现的原因,我们仅需套用成员变量的接口即可,这也是我让各位复习一下vector的原因,下面给出代码:

void push(T x)  //此时我们不晓得插入啥类型的元素,这就看我们显示实例化我们想要显示的了
{s1.push_back(x);
}

1.3.出栈函数pop()的模拟实现

和小编上面实现入栈函数一样,对于出栈函数,我们也是仅需套用一下s1的接口即可,通过上图我们可以知道此时的出栈操作,对应着的就是把vector对象的尾部删除,所以我们调用尾删函数即可,下面给出代码:

void pop()
{s1.pop_back();
}

1.4.判空函数empty()的模拟实现

对于判空函数的模拟实现,也和上面的接口类似,了解vector的朋友都知道,vector里面也是有一个叫做empty()的接口的,我们仅需套用这个接口就好了,下面小编给出代码:

bool empty()
{return s1.empty();
}

1.5.个数函数size()的模拟实现

对于它的模拟实现,我们同样也可以套用vector的相关接口,就可以实现这个个数函数,由于难度不大,不再多说给出代码:

int size()
{return s1.size();
}

1.6.栈顶函数top()的模拟实现

对于栈顶函数的模拟实现,我们需要先知道栈顶是vector哪个位置的元素,通过上图便可以轻松的看出来栈顶就是vector对象最后一个位置的元素,此时我们仅需返回尾部元素即可,此时我们可以套用vector中的back接口,这个接口我虽然没讲,它的功能就是返回vector最后一个位置的元素,名字其实就可以知晓了。下面小编给出代码写法:

T top()
{return s1.back();
}

以上便就是对于stack的模拟实现,是不是灰常的简单,小编当时在经历完某几个容器的模拟实现之后,这一模拟实现stack,就感到了一阵舒爽,我们仅需疯狂的套用接口就好了,剩下的全靠编译器的调用了,等会queue的讲解也会非常的舒服,不过在讲述queue之前,小编先给各位说一个小的知识点,避免读者朋友踩坑。

2.小警示

对于接下来无论是容器还是适配器的模拟实现,各位读者朋友千万不要让模版的声明和定义分离,我忘记我模版说没说过了,对于模板类型的类和函数,它们的声明和定义是不可以去分离的,这涉及到了分离编译的知识,这部分的知识点小编通过一个图带各位简单的了解下,更为详细的知识我会在模版进阶文章进行讲述,其中的过程通过下图便可以知晓为什么模版的声明和定义是无法分离的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所以我们在进行模拟实现的时候,直接把声明和定义放在一个头文件即可,这个知识点要牢记,防止一些读者朋友犯迷糊。

3.queue的模拟实现

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在讲述这个小警示以后,紧接着我们就要开始进入queue的模拟实现了,相信看完前文的stack的模拟实现后,各位应该对于queue的模拟实现也会信心满满,因为queue的接口中设计了一端进一端出,因此此时我们用vector封装的话效率会变的很低,根据以前我们数据机构队列的实现的检验来看,用双链表是一个不错的选择,而恰好我们之前list就是一个典型的双链表结构,所以此时我们就是用list来帮助我们实现queue的模拟实现,下面我们就进入queue的模拟实现。

3.1.queue类的初步实现

首先我们需要先完成queue的外部的书写,此时和stack一样,为了防止命名冲突,我们需要把它放置在我们自己的命名空间内,然后完成一个模板类的书写,之后我们再和标准库的queue一样书写模版参量,之后我们在写一个Container类型的对象就好了,把它作为我们的成员变量,通过它实现出队列的增删等操作,下面给出这层外套:

namespace wang
{template<class T,class Container = list<T>>class queue{private:Container s1;};
}

3.2.入队列函数push()的模拟实现

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于入队列函数,此时我们需要按照队列的结构来对于list对象接口进行合理使用,此时我们知道入队列是从队尾入,所以此时我们需要用到list里面的尾插接口来帮助我们实现这个功能,下面小编给出这个代码的书写:

void push(T x)
{s1.push_back(x);
}

3.3.出队列函数pop()的模拟实现

对于出队列函数,我们依照队列的结构,发现它是从队头进行出队列操作,所以此时我们就要借助list对象的头删函数来帮助我们完成出队列操作,下面小编给出这个代码的书写:

void pop()
{s1.poo_front();
}

3.4.取队头函数front()的模拟实现

这个函数的功能名字就可以体现出来,此时我们如果想要取出队头,就需要知道是s1的一个我也没讲过的接口,front()接口,它的功能就是取出双链表第一个有效结点的元素,所以它正好就可以取出队头元素,下面给出代码书写:

T front()
{return s1.front();
}

3.5.取队尾函数back()的模拟实现

这个函数的功能同样通过名字就可以体现出来,此时我们想要取出队尾,就需要知道s1的back()接口,他和vector一样,都是取出最后一个位置的元素,用它便可以取出队尾的元素,下面给出代码:

T back()
{return s1.back();
}

3.6.判空函数empty()的模拟实现

对于判空函数,无非就是判断队列里面是否为空,无非就是检查成员变量是否为空,此时我们仅需调用list对象的判空函数即可,下面小编给出代码:

bool empty()
{return s1.empty();
}

3.7.个数函数size()的模拟实现

我们如果想要知道队列里面有几个有效元素,直到成员对象里面有几个有效元素即可,此时我们仅需套用它的size()函数即可,下面给出代码:

int size()
{return s1.size();
}

以上便就是小编对于queue的模拟实现,此时此刻的你是不是感受到了“套娃”的魅力,对于适配器的模拟实现,我们仅需知道合适的容器就好了,剩下的就是无限的套用,只能说用起来十分的舒适,容器的模拟实现我认为是很复杂的,这就是我到现在都没有书写容器的模拟实现的原因(咳咳其实也是懒的写),下面我把这些代码整合起来来帮助各位知晓一个完整的模拟实现。

4.代码展示

4.1.stack

namespace wang
{template<class T,class Container = std :: vector<T>>class stack{public:void push(T x){s1.push_back(x);}void pop(){s1.pop_back();}bool empty(){return s1.empty();}int size(){return s1.size();}T top(){return s1.back();}private:Container s1;};
}

4.2.queue

namespace wang
{template<class T,class Comtainer = std :: list<T> >class queue{public:void push(T x){s1.push_back(x);}void pop(){s1.pop_front();}int size(){return s1.size();}T front(){return s1.front();}T back(){return s1.back();}bool empty(){return s1.empty();}private:Comtainer s1;};
}

`

5.总结

此时此刻小编就完成了栈和队列的模拟实现,是不是很轻松,这直接套用别的容器接口的感觉就是舒服,如果容器的模拟实现也是这样该多好(当然不可能),希望后来的我可以完成各种容器的模拟实现文章的书写,感觉写一篇相关类型的文章可以帮助我更好的成长,如果文章有错误,可以在评论区点出,我会定期的回复读者朋友,那么各位大佬们,我们下一篇文章见啦!
在这里插入图片描述

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

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

相关文章

刷题日常(数据流中的中位数,逆波兰表达式求值,最长连续序列,字母异位词分组)

数据流中的中位数 描述 如何得到一个数据流中的中位数&#xff1f;如果从数据流中读出奇数个数值&#xff0c;那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值&#xff0c;那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()…

SQL 复杂查询

目录 复杂查询 一、目的和要求 二、实验内容 &#xff08;1&#xff09;查询出所有水果产品的类别及详情。 查询出编号为“00000001”的消费者用户的姓名及其所下订单。&#xff08;分别采用子查询和连接方式实现&#xff09; 查询出每个订单的消费者姓名及联系方式。 在…

uniapp-vue2引用了vue-inset-loader插件编译小程序报错

报错信息 Error: Vue packages version mismatch: - vue3.2.45 (D:\qjy-myApp\admin-app\node_modules\vue\index.js) - vue-template-compiler2.7.16 (D:\qjy-myApp\admin-app\node_modules\vue-template-compiler\package.json) This may cause things to work incorrectly.…

VOLO实战:使用VOLO实现图像分类任务(二)

文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度&#xff0c;DP多卡&#xff0c;EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…

【Linux】TCP网络编程

目录 V1_Echo_Server V2_Echo_Server多进程版本 V3_Echo_Server多线程版本 V3-1_多线程远程命令执行 V4_Echo_Server线程池版本 V1_Echo_Server TcpServer的上层调用如下&#xff0c;和UdpServer几乎一样&#xff1a; 而在InitServer中&#xff0c;大部分也和UDP那里一样&…

XG(S)-PON原理

前言 近年来&#xff0c;随着全球范围内接入市场的飞快发展以及全业务运营的快速开展&#xff0c;已有的PON技术标准在带宽需求、业务支撑能力以及接入节点设备和配套设备的性能提升等方面都面临新的升级需求XG(S)-PON(10G GPON)是在已有GPON技术标准上演进的增强下一代GPON技…

C语言学习 12(指针学习1)

一.内存和地址 1.内存 在讲内存和地址之前&#xff0c;我们想有个⽣活中的案例&#xff1a; 假设有⼀栋宿舍楼&#xff0c;把你放在楼⾥&#xff0c;楼上有100个房间&#xff0c;但是房间没有编号&#xff0c;你的⼀个朋友来找你玩&#xff0c;如果想找到你&#xff0c;就得挨…

前端---CSS(部分用法)

HTML画页面--》这个页面就是页面上需要的元素罗列起来&#xff0c;但是页面效果很差&#xff0c;不好看&#xff0c;为了让页面好看&#xff0c;为了修饰页面---》CSS CSS的作用&#xff1a;修饰HTML页面 用了CSS之后&#xff0c;样式和元素本身做到了分离的效果。---》降低了代…

H.265流媒体播放器EasyPlayer.js无插件H5播放器关于移动端(H5)切换网络的时候,播放器会触发什么事件

EasyPlayer.js无插件H5播放器作为一款功能全面的H5流媒体播放器&#xff0c;凭借其多种协议支持、多种解码方式、丰富的渲染元素和强大的应用功能&#xff0c;以及出色的跨平台兼容性&#xff0c;为用户提供了高度定制化的选项和优化的播放体验。无论是视频直播还是点播&#x…

零基础学安全--云技术基础

目录 学习连接 前言 云技术历史 云服务 公有云服务商 云分类 基础设施即服务&#xff08;IaaS&#xff09; 平台即服务&#xff08;PaaS&#xff09; 软件即服务&#xff08;SaaS&#xff09; 云架构 虚拟化 容器 云架构设计 组件选择 基础设施即代码 集成部署…

【AI绘画】Midjourney进阶:色调详解(上)

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;Midjourney中的色彩控制为什么要控制色彩&#xff1f;为什么要在Midjourney中控制色彩&#xff1f; &#x1f4af;色调白色调淡色调明色调 &#x1f4af…

前端适配:常用的几种方案

一、rem和第三方插件 rem与em不同&#xff0c;rem会根据html的根节点字体大小进行变换&#xff0c;例如1rem就是一个字体大小那么大&#xff0c;比如根大小font size为12px&#xff0c;那么1rem即12px&#xff0c;大家可以在网上寻找单位换算工具进行换算&#xff08;从设计稿…

蓝桥杯c++算法秒杀【6】之动态规划【下】(数字三角形、砝码称重(背包问题)、括号序列、异或三角:::非常典型的必刷例题!!!)

别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01;! ! ! ! &#xff01; 关注博主&#xff0c;更多蓝桥杯nice题目静待更新:) 动态规划 三、括号序列 【问题描述】 给定一个括号序列&#xff0c;要求尽可能少地添加若干括号使得括号序列变得合…

AIGC--AIGC与人机协作:新的创作模式

AIGC与人机协作&#xff1a;新的创作模式 引言 人工智能生成内容&#xff08;AIGC&#xff09;正在以惊人的速度渗透到创作的各个领域。从生成文本、音乐、到图像和视频&#xff0c;AIGC使得创作过程变得更加快捷和高效。然而&#xff0c;AIGC并非完全取代了人类的创作角色&am…

Hot100 - 字母异位词分组

Hot100 - 字母异位词分组 最佳思路&#xff1a;排序 时间复杂度&#xff1a; O(nmlogm)&#xff0c;其中 n 为 strs 数组的长度&#xff0c;m 为每个字符串的长度。 代码&#xff1a; class Solution {public List<List<String>> groupAnagrams(String[] strs) …

C++11特性(详解)

目录 1.C11简介 2.列表初始化 3.声明 1.auto 2.decltype 3.nullptr 4.范围for循环 5.智能指针 6.STL的一些变化 7.右值引用和移动语义 1.左值引用和右值引用 2.左值引用和右值引用的比较 3.右值引用的使用场景和意义 4.右值引用引用左值及其一些更深入的使用场景分…

【H2O2|全栈】JS进阶知识(十一)axios入门

目录 前言 开篇语 准备工作 获取 介绍 使用 结束语 前言 开篇语 本系列博客主要分享JavaScript的进阶语法知识&#xff0c;本期主要对axios进行基本的了解。 与基础部分的语法相比&#xff0c;ES6的语法进行了一些更加严谨的约束和优化&#xff0c;因此&#xff0c;在…

【前端】ES6基础

1.开发工具 vscode地址 :https://code.visualstudio.com/download, 下载对应系统的版本windows一般都是64位的 安装可以自选目录&#xff0c;也可以使用默认目录 插件&#xff1a; 输入 Chinese&#xff0c;中文插件 安装&#xff1a; open in browser&#xff0c;直接右键文件…

代码美学:MATLAB制作渐变色

输入颜色个数n&#xff0c;颜色类型&#xff1a; n 2; % 输入颜色个数 colors {[1, 0, 0], [0, 0, 1]}; createGradientHeatmap(n, colors); 调用函数&#xff1a; function createGradientHeatmap(n, colors)% 输入检查if length(colors) ~ nerror(输入的颜色数量与n不一…

【Reinforcement Learning】强化学习下的多级反馈队列(MFQ)算法

&#x1f4e2;本篇文章是博主强化学习&#xff08;RL&#xff09;领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对相关等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅…