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

【c++】stack和queue模拟实现

> 作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等
> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:能手撕stack和queue模拟

> 毒鸡汤:过错是暂时的遗憾,而错过则是永远的遗憾!

> 望小伙伴们点赞👍收藏✨加关注哟💕💕 

🌟前言

        手撕stack和queue对比在数据结构中的模拟要比较简单,为什么呢?因为我们学习了参数模板这块,我们可以调用,所以模拟起来比较简单,具体是如何简单法呢,我们进入正文:

⭐主体

这里我们创建三个文件:stack.h,queue.h,test.cpp。


第一个:迭代器模式
迭代器模式就是在不暴露底层的细节的前提下,通过封装给用户提供统一的接口让用户访问容器里面的数据,我们使用的每个容器都可以通过创建迭代器变量的方式来访问容器里面的内容,并且访问的方式都是一样的,(*迭代器变量)可以得到并修改指定位置的数据,(迭代器++)可以让迭代器变量指向容器的下一个元素,通过上面的两个操作,不管是vector容器还是string容器还是后面要学的更加复杂的容器,我们都可以很简单的访问容器里面的内容,但是这些迭代器底层实现的原理是一样的吗?vector和string迭代器是通过创建一个指针变量来实现的,而list迭代器是创建一个类,通过这个类对list的数据进行封装来实现的,不同的容器的迭代器实现的方法也各不相同,但是作为使用者来说我们根本就不用了解这些迭代器的底层实现我们会用就行,并且迭代器的出现很大程度上降低了我们学习的成本,并且迭代器的出现还有助于维护数据的安全,如果我们认为的操作容器里面的数据的话,搞不好就将哪个重要的数据删除了,将另外一个地方的数据覆盖了,所以迭代器模式就对容器里面的数据进行了一下封装,我们要访问这些数据就只能通过迭代器的方式来进行访问,这样即降低了学习成本又保护了数据的安全,我们把这样的设计模式成为迭代器模式。
第二个:适配器模式
在之前的学习中我们知道stack对数据管理的方式是先入栈的数据后出栈,后入栈的数据先出栈,我们还知道queue对数据管理的方式是:先入队列的数据先出队列,后入队列的数据后出队列,这是两个容器对数据处理的方式,虽然这种处理数据的方式属于这些容器的,但是其他的容器也可以实现这样的功能,比如说vector和list都可以在容器的头部或者尾部插入或删除数据,如果我们只让vector或者list在容器的头部尾部插入删除数据的话,那是不是就相当于是stack了呢?如果我们只让vector或者list在头部删除数据在尾部插入数据的话,那这是不是就相当于queue了呢?所以在实现一个容器或者功能的时候,我们可以用现有东西进行一些简单的修改或者封装从而实现你想要的东西,那么这就是适配器模式:用已有的东西通过封装转换出来你想要的东西,那么我们这里的stack和queue就可以通过适配器模式来实现。

🌙stack模拟实现

       模拟实现C++的栈时,应该要考虑用什么作为它的底层,目前来看,貌似动态数组vector是个不错的选择,因为栈只需要在栈顶插入和删除元素。

        第二个模板参数的默认值给成vector<T>,这样就不需要用户自己传递第二个参数了。实现stack中的函数也很容易,只需要在函数内部调用vector的函数即可。

框架如下:

#include<iostream>
#include<vector>
#include<list>using namespace std;
namespace lyk
{template<class T, class continer = vector<int>>class stack{public:private:continer con;};
}

💫元素入栈

首先来实现一下stack的push函数因为stack在插入数据的时候只能在尾部插入数据,所以在stack的push函数里面就可以直接调用容器con的push_back函数来尾插数据,那么该函数的实现如下:

// 元素入栈
void push(const T& val)
{con.push_back(val);
}

💫元素出栈

stack中删除数据也只能删除尾部数组,所以实现pop函数的时候就可以直接调用容器con的pop_back函数来删除数据,那这里的代码就如下:

// 元素出栈
void pop()
{con.pop_back();
}

💫获取元素有效个数

复用vector类的函数即可获得有效元素的个数,代码如下:

// 返回栈中元素个数
size_t size()
{return con.size();
}

💫判断栈是否为空

复用vector类的判空函数,代码如下:

// 判断栈是否为空
bool empty()
{return con.empty();
}

💫返回栈顶元素

代码如下:

// 返回栈顶元素
const T& top()
{return con.back();
}

💫stack整体代码

#include<iostream>
#include<vector>
#include<list>using namespace std;
namespace lyk
{template<class T, class continer = vector<int>>class stack{public:// 元素入栈void push(const T& val){con.push_back(val);}// 元素出栈void pop(){con.pop_back();}// 返回栈中元素个数size_t size(){return con.size();}// 判断栈是否为空bool empty(){return con.empty();}// 返回栈顶元素const T& top(){return con.back();}private:continer con;};// 测试void test_stack(){lyk::stack<int> s1;s1.push(1);s1.push(2);s1.push(3);s1.push(4);while (!s1.empty()){cout << s1.top() << " ";s1.pop();}cout << endl;lyk::stack<int, list<int>> s2;s2.push(4);s2.push(3);s2.push(2);s2.push(1);while (!s2.empty()){cout << s2.top() << " ";s2.pop();}}
}

运行结果:

🌙queue模拟实现

同样的道理queue也要容纳各种数据,也可以由各种容器作为底层来容纳数据,所以queue也得创建一个模板,并且模板里面也得有两个参数,因为queue是在容器的头部删除数据,在容器的尾部插入数据,所以给第二个参数的缺省值最好是deque,那么这里的代码就如下:

#include<iostream>
#include<vector>
#include<list>
#include<deque>namespace lyk
{template<class T, class continer = deque<T>>class queue{public:private:continer con;};}

💫元素入队列

因为queue插入数据是在容器的尾部插入数据,所以在实现queue的push函数时可以通过调用con的push_back函数来实现,那这里的代码如下:

// 元素入队列
void push(const T& val)
{con.push_back(val);
}

💫元素出队列

queue的pop函数是在容器的头部删除数据所以这里可以调用容器的pop_front函数来实现,那么这里的代码如下:

// 元素出队列
void pop()
{con.pop_front();
}

💫返回队列元素个数

调用内部容器函数来进行实现,那么这里的代码就如下:

// 返回队列元素个数
size_t size()
{return con.size();
}

💫判断队列是否为空

调用内部容器函数来进行实现,那么这里的代码就如下:

// 判断队列是否为空
bool empty()
{return con.empty();
}

💫返回队头元素的引用

调用内部容器函数来进行实现,那么这里的代码就如下:

// 返回队头元素的引用
const T& front()
{return con.front();
}

💫返回队头元素的引用

调用内部容器函数来进行实现,那么这里的代码就如下:

// 返回队头元素的引用
const T& back()
{return con.back();
}

💫queue整体代码

#include<iostream>
#include<vector>
#include<list>
#include<deque>namespace lyk
{template<class T, class continer = deque<T>>class queue{public:// 元素入队列void push(const T& val){con.push_back(val);}// 元素出队列void pop(){con.pop_front();}// 返回队列元素个数size_t size(){return con.size();}// 判断队列是否为空bool empty(){return con.empty();}// 返回队头元素的引用const T& front(){return con.front();}// 返回队头元素的引用const T& back(){return con.back();}private:continer con;};void test_queue(){//bit::queue<int> q;// // vector不能适配//bit::queue<int, vector<int>> q;lyk::queue<int, list<int>> q;q.push(1);q.push(2);q.push(3);q.push(4);while (!q.empty()){cout << q.front() << " ";q.pop();}cout << endl;}}

运行结果:

   🌟结束语

       今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小手给博主一键三连,有你们的支持是我最大的动力💞💞💞,回见。

相关文章:

  • 深度神经网络联结主义的本质
  • 【Django】执行查询—跨关系查询中的跨多值关联问题
  • 位运算第二弹
  • 单词倒排——c语言解法
  • proteus8.15图文安装教程
  • ShardingJdbc实战-ShardingJdbc配置及读写分离
  • [FT]chatglm2微调
  • 【C++从0到王者】第四十六站:图的深度优先与广度优先
  • STM32USART串口数据包
  • 字典树基础,朴素字符串查找
  • MySQL 用户账号迁移
  • 小白的matlab简单应用
  • 【打工日常】使用docker部署在线PDF工具
  • 基于MUSIC算法的六阵元圆阵DOA估计matlab仿真
  • 《TCP/IP详解 卷一》第9章 广播和组播
  • 【Leetcode】101. 对称二叉树
  • JavaScript-如何实现克隆(clone)函数
  • C++类中的特殊成员函数
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • Node项目之评分系统(二)- 数据库设计
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • PhantomJS 安装
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • Promise面试题,控制异步流程
  • python大佬养成计划----difflib模块
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 深度学习在携程攻略社区的应用
  • 实现菜单下拉伸展折叠效果demo
  • 项目实战-Api的解决方案
  • 一个SAP顾问在美国的这些年
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • 移动端高清、多屏适配方案
  • ​ubuntu下安装kvm虚拟机
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (未解决)macOS matplotlib 中文是方框
  • ../depcomp: line 571: exec: g++: not found
  • .NET 中让 Task 支持带超时的异步等待
  • .NET建议使用的大小写命名原则
  • .net网站发布-允许更新此预编译站点
  • .NET序列化 serializable,反序列化
  • @Resource和@Autowired的区别
  • @RunWith注解作用
  • [BZOJ 1040] 骑士
  • [C++] 默认构造函数、参数化构造函数、拷贝构造函数、移动构造函数及其使用案例
  • [C++]priority_queue的介绍及模拟实现
  • [C语言]一维数组二维数组的大小
  • [Deepin 15] 编译安装 MySQL-5.6.35
  • [Dxperience.8.*]报表预览控件PrintControl设置
  • [E单调栈] lc2487. 从链表中移除节点(单调栈+递归+反转链表+多思路)
  • [hibernate]基本值类型映射之日期类型
  • [Hive] CTE 通用表达式 WITH关键字