1、Stack
(1)定义
栈是一种容器适配器,特别为后入先出而设计的一种(LIFO ),那种数据被插入,然后再容器末端取出。
默认情况下,如果没有容器类被指定成为一个提别的stack 类,标准的容器类模板就是deque 队列。
堆栈是一个线性表,插入和删除只在表的一端进行。这一端称为栈顶(Stack Top),另一端则为栈底(Stack Bottom)。堆栈的元素插入称为入栈,元素的删除称为出栈。由于元素的入栈和出栈总在栈顶进行,因此,堆栈是一个后进先出(Last In First Out)表(queue是FIFO),即 LIFO 表。
(2)底层实现
实现C++ STL,栈有两个参数:
参数示意:
C++ STL 的堆栈泛化是直接通过现有的序列容器来实现的,默认使用双端队列deque的数据结构。
当然,可以采用其他线性结构(vector 或 list等),只要提供堆栈的入栈、出栈、栈顶元素访问和判断是否为空的操作即可。
由于堆栈的底层使用的是其他容器,因此,堆栈可看做是一种适配器,将一种容器转换为另一种容器(堆栈容器)。
为了严格遵循堆栈的数据后进先出原则,stack 不提供元素的任何迭代器操作,因此,stack 容器也就不会向外部提供可用的前向或反向迭代器类型。
拓展:
Q:为什么stack和queue没有迭代器?让这些容器具备迭代器岂不是更方便?
A:一个容器的方法与其本身特性密切联系,stack和queue分别是FILO和FIFO的线性表,不允许其他的进出方式,为了严格遵守这种原则,故不提供迭代器操作。deque是双向队列,提供迭代器。
(3)使用
stack堆栈容器的C++标准头文件为 stack ,必须用宏语句 "#include <stack>" 包含进来,才可对 stack 堆栈的程序进行编译。
2、成员函数
(1)创建 stack 对象
stack堆栈容器的元素入栈函数为push函数。
由于 C++ STL 的堆栈函数是不预设大小的,因此,入栈函数就不考虑堆栈空间是否为满,均将元素压入堆栈,从而函数没有标明入栈成功与否的返回值。
如下是他的使用原型:
示例:
(3)元素出栈
stack容器的元素出栈函数为 pop 函数,由于函数并没有判断堆栈是否为空,才进行元素的弹出,因此,需要自行判断堆栈是否为空,才可执行 pop 函数。
示例:
(4)取栈顶元素
示例:
(5)堆栈非空判断
随着堆栈元素不断出栈,堆栈可能会出现空的情况,因此,一般需要调用 empty 函数判断是否非空,才作元素出栈和取栈顶元素的操作。
示例:
(6)访问栈中的元素个数
堆栈的元素个数可用 size 函数获得。每次元素入栈前,先检查当前堆栈的大小,超过某个界限值,则不允许元素入栈,以此可实现一个具有一定容量限制的堆栈。
示例: