文章目录
-
stack的介绍
-
stack的常用接口
-
stack的模拟实现
-
关于栈的相关OJ题
一、stack的介绍
- 1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。
- 2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。
- 3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作:
- empty:判空操作
- back:获取尾部元素操作
- push_back:尾部插入元素操作
- pop_back:尾部删除元素操作
- 4. 标准容器vector、deque、list均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器,默认情况下使用deque。
二、stack的常用接口
函数说明 接口说明stack() 构造空的栈empty() 检测stack是否为空size() 返回stack中元素的个数top() 返回栈顶元素的引用push() 将元素val压入stack中pop() 将stack中尾部的元素弹出swap() 交换两个容器的内容
相关接口演示:
#include <iostream>
#include <stack>
int main()
{
std::stack<int> st;
st.push(1);
st.push(2);
st.push(3);
while (!st.empty()) {
std::cout << st.top() << " ";
st.pop();
}
return 0;
}
三、stack的模拟实现
#pragma once
namespace Stack
{
//这里默认是采用deque这种适配器来模拟栈
template<class T,class Contain=std::deque<T>>
class stack
{
public:
/*
stack()//这里不需要显示写构造函数,因为是自定义类型,直接调用默认构造函数就行
{}
*/
bool empty()
{
return _con.empty();
}
size_t size()const
{
return _con.size();
}
const T& top()const
{
return _con.back();
}
void push(const T& val)
{
_con.push_back(val);
}
void pop()
{
_con.pop_back();
}
void swap(stack<T, Contain>& st)
{
std::swap(_con, st._con);
}
private:
Contain _con;
};
}
四、关于栈的相关OJ题
1.最小栈OJ链接
本题思路:设置一个辅助栈一个最小栈即可解决问题。
class MinStack {
private:
stack<int> minST;
stack<int> tmpST;
public:
MinStack() {
}
void push(int val) {
tmpST.push(val);
if(minST.empty()||minST.top()>=val)
minST.push(val);
}
void pop() {
if(tmpST.top()==minST.top()){
tmpST.pop();
minST.pop();
}
else
tmpST.pop();
}
int top() {
return tmpST.top();
}
int getMin() {
return minST.top();
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(val);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
2.栈的压入、弹出序列OJ链接
本题思路:本题利用
class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV) {
if(pushV.size()!=popV.size())//前言如果不满足这两个条件则直接返回false
return false;
if(pushV.empty()||popV.empty())
return false;
stack<int> ST;//创建出来一个栈
int i,j=0;
for(i=0;i<pushV.size();i++)//将压栈数组插入到栈中
{
ST.push(pushV[i]);
while(!ST.empty()&&ST.top()==popV[j])//循环进行遍历操作,如果此时的popV[j]==ST.top(),则出栈
{
ST.pop();
j++;
}
}
if(!ST.empty())
return false;
return true;
}
};
3.逆波兰表达式求值OJ链接
本题思路:由于该题时后缀表达式,所以从左往右计算利用操作符就开始计算然后将结果入栈即可。
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<string> stk;
for(auto&str:tokens){
if(str=="+"){
int x=stoi(stk.top());
stk.pop();
int y=stoi(stk.top());
stk.pop();
auto sum=[](int x,int y){
return x+y;
};
stk.push(to_string(sum(x,y)));
}
else if(str=="-"){
int x=stoi(stk.top());
stk.pop();
int y=stoi(stk.top());
stk.pop();
auto sub=[](int x,int y){
return y-x;
};
stk.push(to_string(sub(x,y)));
}
else if(str=="*"){
int x=stoi(stk.top());
stk.pop();
int y=stoi(stk.top());
stk.pop();
auto mul=[](int x,int y){
return x*y;
};
stk.push(to_string(mul(x,y)));
}
else if(str=="/"){
int x=stoi(stk.top());
stk.pop();
int y=stoi(stk.top());
stk.pop();
auto div=[](int x,int y){
return y/x;
};
stk.push(to_string(div(x,y)));
}
else {
stk.push(str);
}
}
return stoi(stk.top());
}
};
4.用栈实现队列OJ链接
本题思路:利用两个栈,一个栈用来出数据,一个用来入数据
class MyQueue {
//定义两个栈一个栈用来出数据,一个栈用来插入数据
private:
stack<int> PushST;
stack<int> PopST;
public:
MyQueue() {
}
//将数据放入插入数据的栈中
void push(int x) {
PushST.push(x);
}
//如果此时出数据的栈空为空时则将数据导入出数据的栈中
int pop() {
if(PopST.empty())
{
while(!PushST.empty())
{
PopST.push(PushST.top());
PushST.pop();
}
}
int ret=PopST.top();
PopST.pop();
return ret;
}
int peek() {
if(PopST.empty())
{ while(!PushST.empty())
{
PopST.push(PushST.top());
PushST.pop();
}
}
return PopST.top();
}
bool empty() {
return PushST.empty()&&PopST.empty();
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/