栈及栈的应用(括号匹配和逆波兰表达式)

栈的概念:一种特殊的线性表,其只允许在固定的一端(末端)进行插入和删除元素的操作。

栈顶:进行数据插入和删除的一端。

栈底:栈顶的另一端。

空栈:不含任何元素的栈。

栈的性质:先进后出


栈的功能:从某种数据元素序列到另一种数据元素序列的改变。

栈的实现:

静态

//静态栈
template<class T, size_t N = 100>
class Stack
{
public:
	void Push(const T& x)//入栈
	{
		if (_size == N)
		{
			throw out_of_rang("stack is full");
		}
		_a[_size++] = x;
	}
	void Pop()//出栈
	{
		assert(_size > 0);//表示还有数据
		--_size;
	}
	T& Top()//栈顶
	{
		return _a[_size - 1];
	}
private:
	T _a[N];
	size_t _size;
};
动态
#include<iostream>
using namespace std;
#include<assert.h>
template<class T>
class Stack
{
public:
	Stack()//构造函数
		:_a(NULL)
		, _size(0)
		, _capacity(0)
	{}
	~Stack()//析构函数
	{
		if (_a)
		{
			delete[] _a;
			_capacity = _size = 0;
		}
	}
	void Push(const T &s)//插入
	{
		Checkcapacity();
		_a[_size++] = s;
	}
	void Pop()//删除
	{
		assert(_size > 0);
		--_size;
	}
	bool empty()//判空
	{
		return _size == 0;
	}
	size_t Size()//元素个数
	{
		return _size;
	}

	T& Top()//输出栈顶元素
	{
		assert(_size > 0);
		return _a[_size - 1];
	}
	void Checkcapacity()
	{
		if (_size >= _capacity)
		{
			_capacity = _capacity == 0 ? 3 : _capacity * 2;
			T* tmp = new T[_capacity];
			for (size_t i = 0; i < _size; ++i)
			{
				tmp[i] = _a[i];
			}
			delete[] _a;
			_a = tmp;
		}
	}
private:
	T* _a;
	size_t _size;
	size_t _capacity;
};
void test()
{
	Stack<int> s;
	s.Push(1);
	s.Push(2);
	s.Push(3);
	s.Push(4);
	
	while (!s.empty())
	{
		cout << s.Top() << endl;
		s.Pop();
	}
	cout << endl;
}
int main()
{
	test();
	system("pause");
	return 0;
}
运行结果:


自己实现的与库函数的对比:


栈的应用一:括号匹配问题

1、括号匹配的情况:

(1)右括号多于左括号

(2)左右括号次序匹配不正确

(3)左括号多于右括号

(4)左右括号匹配正确

2、实现思想:定义一个栈,遇到左括号入栈,遇到右括号时,令栈顶的左括号与右括号进行匹配

当栈为空,右括号多于左括号

当字符串遍历结束之后,栈不为空,左括号多与有括号

当栈顶的左括号与右括号不匹配时,次序不匹配

当字符串遍历结束之后,栈为空,匹配正确

#include<iostream>
using namespace std;
#include<assert.h>
#include<stack>
stack<char> s;
bool IsBrackets(char e)//判断字符是否为空
{
	if (e == '(' || e == ')' || e == '[' || e == ']' || e == '{' || e == '}')
		return true;
	return false;
}
bool MatchBrackets(char * pStr)
{
	assert(pStr);
	int len = strlen(pStr);
	for (int i = 0; i < len; i++)
	{
		if (!IsBrackets(pStr[i]))//不是括号
			continue;
		else
		{
			if (pStr[i] == '(' || pStr[i] == '[' || pStr[i] == '{')//左括号入栈
				s.push(pStr[i]);
			else//右括号
			{
				if (s.empty())//栈顶为空
				{
					cout << "右括号多于左括号" << endl;
					return false;
				}
				char c = s.top();
				if (c == '(' && c == ')' || c == '[' && c == ']' || c == '{' && c == '}')
					s.pop();
				else
				{
					cout << "右左括号次序匹配不正确" << endl;
					return false;
				}
			}
		}
	}
	if (!s.empty())
	{
		cout << "左括号多于右括号" << endl;
		return false;
	}
	cout << "左右括号匹配正确" << endl;
	return true;
}
int main()
{
	char str[100];
	cin >> str;
	MatchBrackets(str);
	system("pause");
	return 0;
}

运行结果:


栈的实现二:逆波兰表达式(先操作数,后操作符)


运算时,第一次出栈的数是右操作数,第二次出栈的是左操作数





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值