【数据结构】栈

       栈是数据结构中非常重要的一种,它的最大特点就是先进后出,我们利用这个特点解决很多问题时都会比较方便。比如:括号匹配问题,逆波兰表达式求值等问题,有时候也需要借助栈将递归转化成循环。

       下面我们将通过顺序存储来简单实现栈:

template <class T>
class Stack
{
public:
	Stack()
		: _data(new T[3])
		, _size(0)
		, _capacity(3)
	{}
	void Push(const T& data)
	{
		_CheckCapacity();
		_data[_size++] = data;
	}
	void Pop()
	{
		assert(_size);
		_size--;
	}
	T& Top()
	{
		return _data[_size - 1];
	}
	T& Top()const
	{
		return _data[size - 1];
	}
	size_t Size()const
	{
		return _size;
	}
	bool Empty()const
	{
		return 0 == _size;
	}
	~Stack()
	{
		if (_data)
		{
			delete[] _data;
			_data = NULL;
			_size = 0;
			_capacity = 0;
		}
	}
private:
	void _CheckCapacity()
	{
		if (_size == _capacity)
		{
			T* tmp = new T[_capacity * 2];
			for (size_t i = 0; i < _capacity; i++)
				tmp[i] = _data[i];
			delete[] _data;
			_data = tmp;
			_capacity = _capacity * 2;
		}
	}
	T* _data;
	size_t _size;//有效元素个数
	size_t _capacity;
};
栈的简单应用

1.括号匹配问题

检查一段表达式中的左右括号是否匹配,如果匹配,返回true,如果不匹配,返回false;不匹配主要包括:左右次序不匹配,左括号多,右括号多三种情况

#include <stack>
bool IsBrackets(char p)
{
	if (p == '(' || p == ')'
		|| p == '[' || p == ']'
		|| p == '{' || p == '}')
		return true;
	return false;
}
bool MatchBrackets(char* pStr)
{
	const char* p = pStr;
	stack<char> s;
	for (int i = 0; p[i] != '\0'; ++i)
	{
		if (!IsBrackets(p[i]))
			continue;
		else
		{
			if (p[i] == '(' || p[i] == '{' || p[i] == '[')
			{
				s.push(p[i]);
				continue;
			}
			if (p[i] == ')' || p[i] == '}' || p[i] == ']')//右括号
			{
				if (s.empty())
				{
					cout << "右括号多于左括号" << endl;//abc)))))
					return false;
				}
				else if (s.top()=='('&&p[i]==')' || s.top()=='{'&&p[i]=='}' || s.top()=='['&&p[i]==']')
					s.pop();
				else
				{
					cout << "左右括号次序不匹配" << endl;
					return false;
				}//else
			}//if右括号
		}
	}//for
	if (s.empty())
	{
		cout << "匹配成功" << endl;
		return true;
	}
	else
	{
		cout << "左括号多于右括号" << endl;
		return false;
	}
}
2.逆波兰式求值

逆波兰式也称后缀表达式,将运算符写在操作数之后,这种表达式,方便于计算机。

#include <stack>
enum OPERATOR
{ADD, SUB, MUL, DIV, DATA};
struct Cell
{
	OPERATOR _op;
	int _data;
};
int CalcRPN(Cell* RPN, int size)
{
	stack<int> s;
	for (int i = 0; i < size; i++)
	{
		if (RPN[i]._op == DATA)
			s.push(RPN[i]._data);
		else
		{
			int right = s.top();
			s.pop();
			int left = s.top();
			s.pop();
			switch (RPN[i]._op)
			{
			case ADD:
				s.push(left + right);
				break;
			case SUB:
				s.push(left - right);
				break;
			case MUL:
				s.push(left * right);
				break;
			case DIV:
				if (right != 0)
					s.push(left / right);
				break;
			}//switch
		}
	}//for
	return s.top();
}
void FunTest()
{
	Cell RPN[] = { { DATA, 12 }, { DATA, 3 }, { DATA, 4 }, { ADD, 0 }, { MUL, 0 }, { DATA, 6 }, { SUB, 0 }, { DATA, 8 }
	, { DATA, 2 }, { DIV, 0 }, { ADD, 0 } };
	int tmp = CalcRPN(RPN, sizeof(RPN) / sizeof(RPN[0]));
	cout << tmp << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值