stack和queue

stack:后进先出,只能在栈顶操作
queue:先进先出,队尾插入push,队头删除pop

方法:
empty,size,push,pop

栈特有:top
队列特有:back,front
在这里插入图片描述
题目链接

class MinStack {
private:
    stack<int> s;
    stack<int> mins;
public:
/*
题目要求:常数时间内检索到最小元素的栈。
可以设置一个min来保存最小元素,但是如果这个最小的出栈了,那当前栈的min就要更新,还要重新去找,显然是不合理的
有一种想法:另设一个栈,来保存每次增加一个元素后,当前栈的最小
例如: 入栈:3,7,6,5,1
栈    保存min的栈
1     1
5     3
6     3
7     3
3     3 
栈每出一个元素,对应的min栈也要出一个元素
*/
    MinStack() {

    }
    
    void push(int val) {
        s.push(val);
        if(mins.empty()||mins.top()>val)//minstack是空栈或者,新入栈的元素小于当前top,push新入栈元素
        mins.push(val);
        else mins.push(mins.top());//否则,还要把top再push一次,要和stack一一对应
    }
    
    void pop() {
        s.pop();
        mins.pop();
    }
    
    int top() {
        return s.top();
    }
    
    int getMin() {
        return mins.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();
 */

提到栈,就不得不提及逆波兰表达式

逆波兰表达式:
逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。
平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。
逆波兰表达式主要有以下两个优点:

  • 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
  • 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中

在这里插入图片描述
题目链接

#include<iostream>
#include<stack>
using namespace std;
#include<string>
#include<vector>

int evalRPN(vector<string>& tokens) {
	stack<string> s;
	for (auto x : tokens)
	{
		//x.size()==1是为了去除负数的情况
		if (x.size() == 1 && (x[0] == '+' || x[0] == '-' || x[0] == '/' || x[0] == '*'))
		{
			int n1, n2;//注意n1,n2的顺序
			// 1,2,/  应该让n2先获取    这样才是  1 / 2
			n2 = stoi(s.top());
			s.pop();
			n1 = stoi(s.top());
			s.pop();
			switch (x[0])
			{
			case '+':n1 += n2; break;
			case '-':n1 -= n2; break;
			case '*':n1 *= n2; break;
			case '/':n1 /= n2; break;
			}
			s.push(to_string(n1));
		}
		else
			s.push(x);
		cout << s.top() << endl;;
	}
	return stoi(s.top());
}

int main()
{
	vector<string> tokens = {"4", "13", "5", "/", "+"};
	evalRPN(tokens);
}

栈模拟实现

#pragma once

#include<vector>
namespace gyx
{
	//用vector作为stack的底层数据结构
	template<class T,class Container=std::vector<T>>
	class stack
	{
	private:
		Container c;
	public:
		stack()
		{}

		void push(const T& val){ c.push_back(val); }
		void pop()
		{
			if (c.empty())
				return;
			c.pop_back();
		}

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

		size_t size()const{ return c.size(); }
		bool empty()const{ return c.empty(); }
	};
}

队列模拟实现

#pragma once

#include<list>

namespace gyx
{
	template<class T,class Container=std::list<T>>
	class queue
	{
	private:
		std::list<T> q;
	public:
		queue(){}

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

		void pop()
		{
			if (q.empty())return;
			q.pop_front();
		}

		T& front(){ return q.front(); }
		T& back(){ return q.back(); }
		const T& front()const{ q.front(); }
		const T& back()const{ q.back(); }

		bool empty(){ return q.empty(); }
	};
}

测试:

#include"Stack.h"
#include<iostream>
using namespace gyx;

void test_stack()
{
	stack<int> s;
	for (int i = 0; i < 10;i++)
	s.push(i);
	//for (int i = 0; i < s.size(); i++)//这样遍历对吗?不对,因为size是变化的
	//{
	//	std::cout << s.top()<<" ";
	//	s.pop();
	//}
	while (!s.empty())
	{
		std::cout << s.top() << " ";
		s.pop();
	}
}

#include"Queue.h"
void test_queue()
{
	queue<int> q;
	for (int i = 0; i < 10; i++)
		q.push(i);
	while (!q.empty())
	{
		std::cout << q.front() << " " << q.back() << '\n';
		q.pop();
	}
}
int main()
{
	test_stack();
	test_queue();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值