ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++stack与queue模拟实现

2021-09-11 20:01:26  阅读:187  来源: 互联网

标签:xxxx 适配器 C++ queue vector stack con


C++stack与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的功能特点。

标签:xxxx,适配器,C++,queue,vector,stack,con
来源: https://blog.csdn.net/cdzg_zzk/article/details/120241615

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有