【C++】stack and queue

目录

1. stack

1.1. stack常用接口实现

 2. queue

2.1. 常用接口模拟实现

3. 容器适配器

3.1. 适配器

3.2. STL标准库中stack和queue的底层结构

4.stack&queueOJ题

4.1.最小栈

4.2.栈的弹出、压入序列

4.3. 逆波兰表达式求值


1. stack

STL---stack文档

关于stack是什么和怎么用这里不再介绍。

实现也只是贴代码(毕竟太简单)。

1.1. stack常用接口实现

【C++】stack and queue_第1张图片

这里stack的实现与数据结构阶段的stack实现不同,不会去详细实现底层的结构,而是直接套用其他的容器来实现。所以stack和queue不是容器,而是容器适配器(下面讲)。

 

namespace wt
{
	template > // 第二个模板参数是容器,缺省值为deque(双端队列)
	class stack 
	{
	public:
		stack()  // 因为套用其他容器,可以使用他们自己的构造函数,所以stack的构造函数不用自己实现
		{}

		void push(const T& val)
		{
			_con.push_back(val);
		}

		void pop()
		{
			_con.pop_back();
		}

		const T& top()const
		{
			return _con.back();
		}

		int size()const
		{
			return _con.size();
		}

		bool empty()const
		{
			return _con.size() == 0;
		}
	private:
		container _con;
	};
}

 
2. queue

STL---queue文档

2.1. 常用接口模拟实现

【C++】stack and queue_第2张图片 

namespace wt
{
	template >
	class queue
	{
	public:
		void push(const T& val)
		{
			_con.push_back(val);
		}

		void pop()
		{
			_con.pop_front(); // 注意先进先出
		}

		T front()const
		{
			return _con.front();
		}

		int size()const
		{
			return _con.size();
		}

		bool empty()const
		{
			return _con.size() == 0;
		}
	private:
		container _con;
	};
}

3. 容器适配器

3.1. 适配器

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

3.2. STL标准库中stack和queue的底层结构

虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stack和队列只是对其他容器的接口进行了包装。

STL中stack和queue默认使用deque,比如:

deque文档

至于什么是deque可以自己去了解。。。

 

4.stack&queueOJ题

4.1.最小栈

【C++】stack and queue_第3张图片

方法:

  • 使用两个栈,一个用来放原始数据(s1),一个用来放最小值(s2)
  • 入栈时如果s1放入的数比s2栈顶的小或相等,则将该数也放入s2,否则不放
  • 出栈时如果s1栈顶的数等于s2的栈顶,则s1、s2一起出栈

【C++】stack and queue_第4张图片

 代码如下:

class MinStack {
public:
    MinStack() 
    {}
    
    void push(int val) {
        s1.push(val);
        if(s2.empty()||val<=s2.top()) // s2为空或者入栈数小于等于s2栈顶
        {
            s2.push(val);
        }
    }
    
    void pop() {
        if(s1.top()==s2.top()) // s1.top等于s2.top时
        s2.pop();
        s1.pop();
    }
    
    int top() {
        return s1.top();
    }
    
    int getMin() {
        return s2.top(); // 返回s2栈顶
    }

    private:
    stack s1;
    stack s2;
};

4.2.栈的弹出、压入序列

【C++】stack and queue_第5张图片

方法:

  • 使用一个栈来模拟 该序列的压入
  • 当压入的数与弹出序列的数相等时,从栈中弹出该数,直到没有相等的数为止;否则继续压入
  • 当该序列全部入栈后,如果栈为空则说明压入顺序对应该弹出顺序,否则不对应

【C++】stack and queue_第6张图片

代码如下:

class Solution {
public:
    bool IsPopOrder(vector pushV,vector popV) {
        stack s;
        size_t j = 0;
        for(size_t i = 0; i < pushV.size(); ++i)
        {
            s.push(pushV[i]);
            while(!s.empty()&&s.top()==popV[j]) // 当栈顶与弹出队列相等时,出栈
            {
                s.pop();
                ++j;
            }
        }
        if(s.empty())
        {
            return true;
        }
        else
        {
            return false;
        }
    }
};

 

4.3. 逆波兰表达式求值

【C++】stack and queue_第7张图片

逆波兰表达式又叫做后缀表达式,逆波兰表达式把运算量写在前面,把算符写在后面。 

方法:

  • 用一个栈来存放数字,遍历vector,遇到数字就入栈
  • 如果遇到符号则连续将两个数字出栈进行运算,将运算结果继续入栈
  • 最后栈中就只会剩下最终运算的答案

代码如下:

class Solution {
public:
    int evalRPN(vector& tokens) {
        stack s;
        for(const auto& str:tokens)
        {
            if(str == "+" || str == "-" || str == "*" || str == "/")
            {
                int right = s.top();
                s.pop();
                int left = s.top();
                s.pop();
                switch(str[0])
                {
                    case '+':
                    {
                        s.push(left+right);
                        break;
                    }
                    case '-':
                    {
                        s.push(left-right);
                        break;
                    }
                    case '*':
                    {
                        s.push(left*right);
                        break;
                    }
                    case '/':
                    {
                        s.push(left/right);
                        break;
                    }
                    default:
                        assert(false);
                }
            }
            else
            {
                s.push(stoi(str)); // 将字符串转化成数组入栈
            }
        }
        return s.top();
    }
};

你可能感兴趣的:(C++,stack,queue,C++,后端,开发语言)