C++stack与queue模拟实现
2021/9/11 20:05:17
本文主要是介绍C++stack与queue模拟实现,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
C++stack与queue模拟实现
- 前言
- stack栈
- 适配器
- stack的成员函数
- queue队列
- queue类
- 总结
前言
xxxx无论是当初在学校最先学习C语言版的数据结构,还是现在学习STL,发现大家(包括我)都喜欢将stack(栈)和queue(队列)放在一起。可能是FILO和FIFO两种数据存储方式过于相近,更能深入人心,因此两者经常会被放在一起。但是STL我把他们放在一起更是有原因。因为这两种容器在模拟实现的时候,都会使用到“适配器”。这个在后面我再具体说明。
stack栈
xxxx栈的基本知识相信大家都已经了解,在此我就不再赘述。栈的逻辑结构如图
现在我们就要用C++进行实现。我们当初用C语言实现栈的时候,最多的情况都是使用的数组来模拟栈。数组的头代表数组的栈底;数组的尾代表栈顶。由于栈对数据的push、pop都是在栈顶操作,所以使用数组就能在时间复杂度为O(1)的情况下完成操作,十分高效。
xxxx这里有一个很重要的事情,就是C语言中,我们用数组来模拟栈。那C++呢??数组的结构特点非常适合来作为栈,所以我们能否仍然使用数组(vector)来作为栈的基础数据结构从而实现栈呢?
xxxx答案是肯定的,我们仍然需要使用数组(不是说只能使用数组,只不过数组更普遍,并且STL中的stack就是使用vector来实现的)但是我们知道,栈还有链栈,或者某些特殊要求我们不能使用vector,而是其他的容器更适合当前的操作情况。这时候,为了代码的通用性,避免代码冗余,为了面对不同的需要,我们不用每次都要写一份逻辑相同而使用的容器不同的stack,我们就要引入**“适配器”**的概念。
适配器
提前声明:我在这里讲的适配器,只是适配器的一小部分,对于模拟实现stack和queue所需要的部分。
xxxx什么是适配器?大家现实生活中应该都有许多类型的适配器。比如:家用220V电压是从高压输电线通过电压转变过来的、两孔三孔插头之间转化……功能类似于下图这种。
xxxx简单来说,就是一种转变。而在这里是什么的转变呢?答案是:容器的转变。
xxxx现在我们的目的是使用各种转变成stack。我们就需要模板。类模板详解请点这里。下面我们直接看一下如何使用模板成为适配器。
template<class T, class Container = vector<T>> class stack { private: Container _con; };
以上就是它的基本格式。我们最简单的理解就是,我们将vector进行一次封装。通过成员函数对他的行为进行约束,让他变成具有stack属性的一种新容器,这种容器我们成为stack。
注:STL中使用的是deque,我们使用vector影响不大,使用vector与C语言有很好的联系,方便理解,否则有些同学刚学到这里,还不知道deque是什么,会影响学习
stack的成员函数
namespace zzk { template<class T, class Container = std::deque<T>> class stack { public: //默认成员函数都不用写,就直接使用deque的就行 void push(const T x) { _con.push_back(x); } void pop() { _con.pop_back(); } T top() const { return _con.back(); } size_t size() const { return _con.size(); } bool empty() const { return _con.empty(); } private: Container _con; }; }
xxxx我们可以很容易发现,完全就是对vector成员函数进行一次封装,因为操作逻辑完全一样,所以只需要对vector的行为封装成stack即可完成。
queue队列
xxxx我们在C语言中的队列可以用链表或者数组。
在C++中,我们仍然要使用适配器这种方式,对某种容器进行封装,形成队列。由于vector不支持头删,所以我们要使用deque或者链表。STL中默认使用的是deque。
经过stack的学习,queue应该比较容易理解,我们直接上代码!!
queue类
namespace zzk { template<class T, class Container = std::deque<int>> class queue { public: void push(const T& x) { _con.push_back(x); } void pop() { _con.pop_front(); } T front() { return _con.front(); } bool empty() { return _con.empty(); } size_t size() { return _con.size(); } private: Container _con; }; }
xxxx还是对已有容器的封装,由于逻辑类似,因此我们直接复用原容器的接口即可。
总结
xxxx栈和队列都使用了“适配器”,在这里,适配器的作用就是对现有容器的一种封装,由于操作逻辑相同,因此只需要对接口进行一次封装即可。对于逻辑不相同的。如用vector实现优先队列priority_queue,由于逻辑不相同,就需要加以其他代码,使符合priority_queue的功能特点。
这篇关于C++stack与queue模拟实现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享