C++STL——Stack&Queue

栈和队列

栈和队列是一种容器适配器,其只允许在容器的两端对数据进行操作,其中

  • 栈服从后进先出规则,从栈顶入数据,从栈顶出数据
  • 队列服从先进先出规则,从队列尾入数据,从队列头出数据

C语言栈和队列详解 

Stack和Queue的使用

在C++STL库中,其中有容器名为stack和queue,在C语言中我们已经详细解释过栈和队列的用法以及其代码组成,我们直接来看其在C++中的函数接口

Stack

函数说明接口说明
stack()构造空的栈
empty()检测stack是否为空
size()返回stack中元素的个数
top()返回栈顶元素的引用
push()将元素val压入stack中
pop()将stack中尾部的元素弹出

Queue

函数声明接口说明
queue()构造空的队列
empty()检测队列是否为空,是返回true,否则返回false
size()返回队列中有效元素的个数
front()返回队头元素的引用
back()返回队尾元素的引用
push()在队尾将元素val入队列
pop()将队头元素出队列

值得一提的是,我们在查询Stack和Queue的模板时,我们会发现其模板组成并非只有数据类型,其在数据类型后还有一个Container

在这里的Container是什么?deque又是什么?

Deque

C++在实现栈和队列时,使用了一个新的数据结构:Deque

我们知道,如果使用vector来实现栈和队列,一旦数据数量多起来,扩容的代价十分巨大。而如果使用list来实现,数据的访问会变得相对困难,那有没有一种数据结构,既能使扩容的代价变小,又可以实现数据的随机访问呢?

此时,便诞生了一种新的数据结构:deque

deque由两部分组成,第一个部分是数据存放区,用很多的数组存储数据,第二部分是中枢数组,用来存储每一个数组的地址

在数据存放区中,每一个数组的大小是固定的,以方便快速计算元素的下标对应的数组
在中枢数组中,数据从中间向两边进行存储,以方便向两边进行扩容

而扩容时,数据存放区不需要变动,只需要对中枢数组进行扩容,然后将地址拷贝到扩容后的数组即可,极大提升了效率

那这么优秀的数据结构,有没有什么弊端呢?

当然,deque在数组中间进行插入和删除操作代价非常大

我们不妨思考,假如有一个已经存放了许多数据的deque,我们需要对其中中间一个位置进行插入,会是什么情况呢?


此时,我们有两种选择

  1. 像vector一样,将该位置后面的所有元素全部挪动
  2. 扩容当前数组,只将该数组中后面的元素进行挪动

但是,我们思考两种方法,第一种因为数据并非连续存储,如果想进行移动代价光想想就十分巨大;而对于第二种 ,虽然想象是美好的,但是我们进行该操作时会有一个严重的问题:数组中元素的个数不再对齐,我们在之后进行随机访问时,也就无法计算数据下标对应的元素

所以,deque只在对两端进行数据操作的情况下才表现得优秀
而这恰恰符合栈和队列的要求

模板中的Container

我们再来看,为什么模板中有一个Container呢?

因为我们在文章首就已经说过,栈和队列实际上是一个容器适配器

容器适配器

适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。

栈和队列就如同以上关系一样,栈和队列虽然也是一个数据结构,但是其是由其它数据结构封装完成,其底层实现可能是vector,可能是list,也可能是deque,而模板中的container便是让我们自由去选择用哪一个底层来实现

由图中我们可以很清楚看到,如果我们不传入container,则其默认使用deque

另外,其实际的代码实现其实很简单

以上仅以push举例

我们在实现时,只需要将栈的操作转换成另一底层数据结构的操作,如果我们使用vector则是vector的push_back,如果使用list则是list的push_back。

这也体现了容器命名统一的好处 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值