●ω●博主的博客主页——>Cinema KI
●△● 博主的gitee主页——>IIrving
本文将继续学习STL库,这次是有关栈(Stack)和队列(Queue)的讲解。

文章目录
🤪一、stack的结构
stack文档介绍
栈在结构在数据结构中算是较为简单的一类了。其接口少且好理解
| stack() | 制造空的栈 |
|---|---|
| empty() | 检测栈是否为空 |
| size() | 返回栈中的元素个数 |
| top() | 返回栈顶元素 |
| push() | 将数据压栈 |
| pop() | 将数据弹出 |
什么是容器适配器?,回到栈的构造那里。
std::stack
template <class T, class Container = deque<T> > class stack;
你看栈有两个参数。第一个T是栈里存的数据类型(比如int、string)。第二个Container是底层用哪个容器——意思是,stack默认“借用”了deque当底层容器,这就是适配器的核心:不自己存数据,借别人的容器使用。
代码示例,如下:
int main()
{
//默认使用deque充当底层结构
std::stack<int> s;
s.push(1);//实际是调用deque的push_back
s.pop();//实际是调用deque的pop_back
return 0;
}
再来看另一个例子
int main()
{
//显示使用vector作stack的底层容器
std::stack<int,std::vector<int>> s;
s.push(1);//实际上是调用vector的push_back
s.pop();//实际上是调用vector的pop_back
return 0;
}
😴1.stack的相关题目(最小栈)
点击这里——>最小栈
题目描述
给你一个类,可以实现像栈那样的功能,但是还有一个成员函数,调用它时就可以取到这个栈当中最小的那个元素。
题目解析
首先这道题需满足栈的基础实现接口,然后再去实现getMin这个函数。我们用两个栈来实现,一个栈正常push\pop数据,另一个栈的栈顶始终存放着前一个栈中数据的最小值。
插入数据
什么时候第二个栈需插入数据?
①当我们第一个栈插入首个元素时(假设插入的数据为5),第二个栈需要插入数据吗?需要,因为此时此刻,第一个栈中的最小值只能是5。
②那如果第二次我们插入的数据为6呢?那么此时第二个栈就不需要插入数据了。因为第一个栈中存放着5、6,但最小为5,刚好第二个栈栈顶为5。
③假设我们插入4,那么就需要往第二个栈插入数据了。此时第一个栈为5、6、4,第二个栈为5、4,栈顶为4,刚好符合。
总结:第一次插入数据,两个栈都要同时插入;每次当插入第一个栈的数据比第二个栈栈顶小或等于时,第二个栈也要插入数据。

删除数据
当删除的元素等于第二个栈栈顶元素,那就两个栈都要出栈顶,否则,只出第一个的栈的栈顶。
🤩 2.stack的相关题目(栈的压入、弹出序列)
点击这里——>栈的压入、弹出序列
题目描述
给定两个整数序列,第一个序列是栈的压入顺序,要判断第二个序列是否是该栈的弹出顺序。要判断压入栈的所有数字均不相等,比如压入顺序是[1,2,3,4,5],弹出顺序[4,5,3,2,1]是可行的,但[4,3,5,1,2]不可行。
解题思路
①先定义两个指针 pushi(指向压入序列的当前元素,初始为0)、popi(指向弹出序列的当前元素,初始为0),同时创建一个辅助栈。
②开始遍历地将压入序列中的元素压入栈中。
–每次压入后,检查栈顶元素是否与弹出序列中popi指向地元素相等。
–若相等,则弹出栈顶元素,并将popi后移一位,直到栈顶与弹出序列当前元素不匹配。
③当压入栈顶序列遍历完成后,判断辅助栈是否为空
–若为空,说明弹出序列符合栈地操作规则;
–若不为空,说明弹出序列不合法。
图文解析

后续栈顶元素跟弹出序列地元素都一一匹配(5跟5,3跟3,2跟2,1跟1),均出栈,最终栈为空,证明弹出序列符合栈地操作规则。
🤣 二、queue的结构
🤯 1.queue的介绍及使用
点击这里——>queue文档介绍
1.队列是一种容器适配器,其中从容器一端插入数据,另一端提取元素。
2.底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作:
| 函数声明 | 接口说明 |
|---|---|
| queue() | 构造空的队列 |
| empty() | 检测队列是否为空,是返回true,否则返回false |
| size() | 返回队列中有效个数的个数 |
| front() | 返回队头元素的引用 |
| back() | 返回队尾元素的引用 |
| push() | 在队尾将元素入队列 |
| 添加链接描述 | 将队头元素出队列 |
😉2.queue的模拟实现
前面说了queue也是一种容器适配器,所以底层也需要vector或者list支持。因为queue的接口存在频繁地对头尾进行操作,所以使用vector进行封装效率太低,故使用list。
代码示例,如下:
#include<iostream>
#include<list>
using namespace std;
namespace Zehong
{
template<class T,class Container = queue<T>>
class queue
{
public:
queue()
{};
void push(const T& x)
{
_con.push.back(x);
}
void pop()
{
_con.pop_front();
}
T& back()
{
return _con.back()
}
T& front()
{
return _con.front();
}
size_t size()
{
return _con.size();
}
bool empty()
{
return _com.empty();
}
private:
Container _con;
};
}
int main()
{
Zehong::queue<int,list<int>> q;
return 0;
}
👀总结
- stack和queue超乖!都不是自己扛事儿的纯容器~靠deque这些“小伙伴”包装成适配器,操作简单到飞起✨
- stack像叠小蛋糕🍰,先放的藏最下面,只能碰最顶上那块;queue就是排小队👫,先来的先走,只许队尾加、队首出!
- 不用纠结它们底下咋运作,记牢各自的小规则,拿来用就好啦~超省心的!😉





