# 数据结构（八）——栈

## 二、栈的实现

### 1、栈的抽象类

``````template <typename T>
class Stack:public Object
{
public:
virtual void push(const T& value) = 0;//入栈
virtual void pop() = 0;//出栈
virtual void clear() = 0;//清空栈
virtual T top()const = 0;//获取栈顶元素
virtual int size()const = 0;//获取栈的大小
};``````

### 2、栈的顺序存储结构实现

A、类模板实现
B、使用原生数组作为栈的存储空间
C、使用模板参数决定栈的容量大小

``````template<typename T, int N>
class StaticStack:public Stack<T>
{
protected:
T m_space[N];//栈存储空间
int m_top;//栈顶标识
int m_size;//当前栈的大小
public:
StaticStack()//构造函数初始化成员
{
m_top = -1;
m_size = 0;
}
int capacity()const//栈的容量
{
return N;
}
void push(const T& value)//压栈
{
if(m_size < N)
{
m_space[m_top + 1] = value;
m_size++;
m_top++;
}
else
{
THROW_EXCEPTION(InvalidOperationException, "No enough memory...");
}
}

void pop()//出栈
{
if(m_size > 0)
{
m_top--;
m_size--;
}
else
{
THROW_EXCEPTION(InvalidOperationException, "No element...");
}
}

T top() const//获取栈顶元素
{
if(m_size > 0)
{
return m_space[m_top];
}
else
{
THROW_EXCEPTION(InvalidOperationException, "No element...");
}
}

void clear()//清空栈
{
m_top = -1;
m_size = 0;
}

int size()const//当前栈的大小
{
return m_size;
}

};``````

### 3、栈的链式存储结构实现

A、类模板实现，继承自抽象父类Stack
C、只在单链表成员对象的头部进行操作

`````` template <typename T>
{
protected:
public:
void push(const T& value)//压栈
{
m_list.insert(0, value);
}
void pop()//出栈
{
if(m_list.length() > 0)
{
m_list.remove(0);
}
else
{
THROW_EXCEPTION(InvalidOperationException, "No element...");
}
}

T top()const//获取栈顶元素
{
if(m_list.length() > 0)
{
return m_list.get(0);
}
else
{
THROW_EXCEPTION(InvalidOperationException, "No element...");
}
}
void clear()//清空栈
{
m_list.clear();
}
int size()const//获取栈大小
{
m_list.length();
}
};``````

## 三、栈的应用

``````bool isLeft(char c)//左符号
{
return (c == '(') || (c == '[') || (c == '{') || (c == '<');
}

bool isRight(char c)//右符号
{
return (c == ')') || (c == ']') || (c == '}') || (c == '>');
}

bool isQuot(char c)//引号、双引号
{
return (c == '\'') || (c == '\"');
}

bool isMatch(char left, char right)//是否匹配
{
return ((left == '(')&&(right == ')')) ||
((left == '[')&&(right == ']')) ||
((left == '{')&&(right == '}')) ||
((left == '<')&&(right == '>')) ||
((left == '\'')&&(right == '\'')) ||
((left == '\"')&&(right == '\"'));
}

bool parse(const char* code)//解析字符串
{
int i = 0;
bool ret = true;
code = (code == NULL)?"":code;
while(ret && (code[i] != '\0'))
{
if(isLeft(code[i]))//左符号
{
stack.push(code[i]);//压栈
}
else if(isRight(code[i]))//右符号
{
//当前字符是右符号，与栈顶元素匹配
if((stack.size() > 0) && isMatch(stack.top(), code[i]))
{
stack.pop();//弹出
}
else
{
ret = false;
}
}
else if(isQuot(code[i]))//引号、双引号
{
//栈为空或当前符号与栈顶元素不匹配
if((stack.size() == 0) || !isMatch(stack.top(), code[i]))
{
stack.push(code[i]);//压栈
}
//当前元素与栈顶元素匹配
else if(isMatch(stack.top(), code[i]))
{
stack.pop();//弹栈
}
}
i++;
}
return ret && (stack.size() == 0);
}``````