栈的概念:一种特殊的线性表,其只允许在固定的一端(末端)进行插入和删除元素的操作。
栈顶:进行数据插入和删除的一端。
栈底:栈顶的另一端。
空栈:不含任何元素的栈。
栈的性质:先进后出
栈的功能:从某种数据元素序列到另一种数据元素序列的改变。
栈的实现:
静态
//静态栈
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;
}
运行结果:
运算时,第一次出栈的数是右操作数,第二次出栈的是左操作数