c++的STL(7) -- stack

stack容器概述

  • stack容器其实是实现了一种和栈相同结构的容器。  

如图,栈这种结构有两端: 栈底和栈顶。  特殊之处在于,这种结构,我们对数据的操作(删除数据,修改数据,查询数据,添加数据)只能在一端进行(栈顶)。是一种后进先出的结构。--  要想读取栈中存储的元素,只能从栈顶读取。


例如:  当我们添加数据的时候,只能从栈顶的位置添加数据。而我们删除数据的时候也只能从栈顶的位置删除。

stack容器的实现 

stack也是一个模板类:

template <class _Ty, class _Container = deque<_Ty>>  class stack {}

上面就是其模板的类型参数,很明显,它接受两个参数,一个是其存储数据的类型,一个则是一个容器类型。 

为什么要接受一个容器类型呢? 

因为stack容器其实是在我们之前学习的vector,deque,list容器的基础上,实现了其它的功能,其内部存储数据还是使用这三个容器(其内部定义了容器的对象)。


为什么要这么做呢?

因为,我们之前学习过的容器功能已经很强大了,但是在某些场景下它们的功能可能并不适用,但是重新开发新的容器也并不高效。

所以我们可以根据我们已有的容器,通过相应的封装和组合,实现对应的功能。

stack就是这样的一个容器,它在vector,deque,list这三个容器的基础之上进行了封装,实现了符合栈结构的容器。(基于这种原理,我们也可以实现我们自己的容器)  --  对于stack而言这三个容器为基础容器。

stack中的函数 

表 stack容器支持的成员函数
成员函数 功能
empty() 当 stack 栈中没有元素时,该成员函数返回 true;反之,返回 false。
size() 返回 stack 栈中存储元素的个数。
top() 返回一个栈顶元素的引用,类型为 T&。如果栈为空,程序会报错。
push(const T& val) 先复制 val,再将 val 副本压入栈顶。这是通过调用底层容器的 push_back() 函数完成的。
push(T&& obj) 以移动元素的方式将其压入栈顶。这是通过调用底层容器的有右值引用参数的 push_back() 函数完成的。
pop() 弹出栈顶元素。
emplace(arg...) arg... 可以是一个参数,也可以是多个参数,但它们都只用于构造一个对象,并在栈顶直接生成该对象,作为新的栈顶元素。
swap(stack<T> & other_stack) 将两个 stack 适配器中的元素进行互换,需要注意的是,进行互换的 2 个 stack 适配器中存储的元素类型以及底层采用的基础容器类型,都必须相同。

注意: 我们前面说到,理论上stack可以使用vector,list,deque三个容器存储数据,但是具体情况还需要根据stack所要实现的功能来定。(就是看实现stack所需要的功能时用到的函数容器支不支持)

对与stack,只要容器支持 empty()、size()、back()、push_back()、pop_back() 这 5 个成员函数就可以作为stack第二个模板类型参数。   --   因为stack是一个先进后出的结构,访问元素只能访问栈顶位置的元素。

1. 创建stack对象 

 创建一个不包含任何参数的对象

stack<int> s1;   // 创建了一个存储int数据的stack对象, 如果我们不传入第二个类型参数,那么默认使用deque作为stack的 基础容器。

指定stack容器的基础容器 

我们可以通过类型参数的第二个参数指定stack的基础容器,但是只能使用vector,list,deque这三个容器中的一个。


stack<int,list<int>>  s1;   // 创建s1,我们指定了list容器作为stack容器的基础容器。

注意:  除去默认情况(使用deque容器为默认情况),我们要使用其它容器作为stack容器的基础容器,需要导入对应容器的头文件。

还有,虽然我们可以指定基础容器,但是默认的基础容器的效率是最高的。


比如:   使用list为基础容器,需要导入list头文件

#include <list> 

#inlcude <stack> 

stack<int,list<int>> s1; 

使用基础容器初始化stack容器。 

注意: 使用基础容器初始化stack容器,必须保证使用的基础容器和stack内部的基础容器是相同的。

deque<int> d1{ 1,2,3,4,5 };

// 使用别的容器初始化
stack<int> s1(d1);   // 使用deque容器的数据初始化stack,此时stack的基础容器应该为deque(也就是默认情况)。

vector<int> v1{ 1,2,3,4,5 };

// 使用别的容器初始化
stack<int,vector<int>> s1(v1);  // 使用vector容器的数据初始化stack,此时stack的容器应该为vector。 

使用别的stack容器给stack初始化 

    vector<int> v1{ 1,2,3,4,5 };
    // 使用别的容器初始化
    stack<int,vector<int>> s1(v1);

    stack<int, vector<int>> s2(s1);   // 方式1:  使用s1初始化s2
    stack<int, vector<int>> s3 = s1; // 方式2:   使用s1初始化s3

2.  stack容器的函数

  • top()函数  --  无需参数

用于获取栈顶元素,函数内部其实是调用了基础容器的back()函数 -- 返回容器的最后的元素。  // 因为栈顶位置的元素是后进去的,对于基础容器而言就是容器最后的元素(可以通过back()函数获得)

  • push(elem)函数

用于压栈(就是往栈里面写数据),将数据压入栈中,函数内部其实是调用了基础容器的push_back()函数,将元素添加到基础容器的尾部。(因为栈是从栈顶元素添加数据,就相当于基础容器在尾部添加元素)

因为底层是push_back()所以其添加元素的形式,也是先拷贝数据,然后再将数据放到对应的位置上。

  • pop()函数  --  无需参数

用于出栈(就是从栈里面删除数据),函数内部其实是调用了基础容器的pop_back()函数,将元素从基础容器的尾部删除掉。(因为栈是从栈顶元素删除数据,就相当于基础容器在尾部删除元素)

  • 其余函数

其余函数和上面函数是一样的,都是通过调用内部基础容器的相应函数来实现功能,但是其用法和基础容器对应函数的用法是一样的,所以就不再说明了。

3. stack没有迭代器 

stack容器是没有迭代器的,我们使用迭代器的目的就是遍历容器中的数据,方便我们对当中的元素进行访问和操作,通过迭代器,可以访问到任意位置的元素。

但是stack是栈,其需求是只能从栈顶查询元素,只能从栈顶删除和插入元素, 可以看出栈我们只能从栈顶操作数据,我们使用相应的函数就可以实现,并不需要使用迭代器。

因为stack结构的原因,我们只能在栈顶添加和删除元素,而且只能访问栈顶元素,如果想要访问其它的元素,就要将其后面的元素一一出栈(栈顶),让其变成栈顶元素,这样我们才能访问到。 --  而使用迭代器,可以直接访问任意位置的元素,就会破坏这种结构。

相关推荐

  1. C++中STL——stack基本使用

    2024-04-06 23:00:04       38 阅读
  2. C++ STL中Queue和Stack用法

    2024-04-06 23:00:04       35 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-06 23:00:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-06 23:00:04       101 阅读
  3. 在Django里面运行非项目文件

    2024-04-06 23:00:04       82 阅读
  4. Python语言-面向对象

    2024-04-06 23:00:04       91 阅读

热门阅读

  1. 【LeetCode热题100】【堆】数组中的第K个最大元素

    2024-04-06 23:00:04       45 阅读
  2. 安卓手机开发的APP配置信息文件的概述

    2024-04-06 23:00:04       37 阅读
  3. 平滑处理在眼动追踪数据分析中的应用

    2024-04-06 23:00:04       46 阅读
  4. C#网页打印功能实现

    2024-04-06 23:00:04       44 阅读
  5. 深入解析Cookie、Session以及Token原理

    2024-04-06 23:00:04       103 阅读
  6. 给已存在的docker容器修改端口映射

    2024-04-06 23:00:04       42 阅读
  7. C++allocator类

    2024-04-06 23:00:04       197 阅读
  8. 针对于医疗行业提供合适的服务器解决方案

    2024-04-06 23:00:04       39 阅读
  9. 关于 Linux Shell文件的三个时间

    2024-04-06 23:00:04       44 阅读
  10. 【XZ-Utils供应链后门漏洞(CVE-2024-3094)】

    2024-04-06 23:00:04       41 阅读
  11. 07 dto

    2024-04-06 23:00:04       36 阅读
  12. c++运算符大全

    2024-04-06 23:00:04       44 阅读
  13. html基础介绍

    2024-04-06 23:00:04       35 阅读