堆栈和队列可能是使用频率最高的数据结构,这里主要记录有关堆栈的一些用法和应用,由于堆栈是一种特殊的线性表,因此可以很自然地从相应的线性表类中派生出堆栈类。
可以派生出基于公式描述的堆栈类,也可以派生出基于链表结构的堆栈类。通过类的派生,可以大大简化程序设计的任务,但同时代码的执行效率有明显损失。由于堆栈是一个很基本的数据结构,许多程序都要用到堆栈,为了消除程序的额外开销,可以把Stack定义成一个基类,而不是一个派生类。
自定义Stack如下:
template<class T>
class Stack {
// LIFO objects
public:
Stack(int MaxStackSize = 10);
~Stack() {delete [] stack;}
bool IsEmpty() const {return top == -1;}
bool IsFull() const {return top == MaxTop;}
T Top() const;
Stack<T>& Add(const T& x);
Stack<T>& Delete(T& x);
private:
int top; // current top of stack
int MaxTop; // max value for top
T *stack; // element array
};
template<class T>
Stack<T>::Stack(int MaxStackSize)
{// Stack constructor.
MaxTop = MaxStackSize - 1;
stack = new T[MaxStackSize];
top = -1;
}
template<class T>
T Stack<T>::Top() const
{// Return top element.
if (IsEmpty()) throw OutOfBounds(); // Top fails
return stack[top];
}
template<class T>
Stack<T>& Stack<T>::Add(const T& x)
{// Add x to stack.
if (IsFull()) throw NoMem(); // add fails
stack[++top] = x;
return *this;
}
template<class T>
Stack<T>& Stack<T>::Delete(T& x)
{// Delete top element and put in x.
if (IsEmpty()) throw OutOfBounds(); // delete fails
x = stack[top--];
return *this;
}
应用:括号匹配
在这个问题中将要匹配一个字符串中的左、右括号。例如,字符串 (a*
(b+c)+d)在位置1和4有左括号,在位置8和11有右括号。位置1的左括号匹配位置11
的右括号,位置4的左括号匹配位置8的右括号。对于字符串 (a+b))(,位置6的右括
号没有可匹配的左括号,位置 7的左括号没有可匹配的右括号。我们的目标是编写
一个 C++程序,其输入为一个字符串,输出为相互匹配的括号以及未能匹配的括
号。注意,括号匹配问题可用来解决 C++程序中的{和}的匹配问题。
可以观察到,如果从左至右扫描一个字符串,那么每个右括号将与最近遇到的
那个未匹配的左括号相匹配。这种观察结果使我们联想到可以在从左至右的扫描过程
中把所遇到的左括号存放到堆栈内。每当遇到一个右括号时,就将它与栈顶的左括号
(如果存在)相匹配,同时从栈顶删除该左括号。
产生匹配括号的程序:
#include <iostream.h>
#include <string.h>
#include <stdio.h>
#include "stack.h"
const int MaxLength = 100; // 最大的字符串长度
void PrintMatchedPairs(char *expr)
{// 括号匹配
Stack<int> s(MaxLength);
int j, length = strlen(expr);
// 从表达式 expr 中搜索 ( 和 )
for (int i = 1; I<=length; i++) {
if (expr[i - 1] ==' ( ' ) s.Add(I);
else if (expr[i - 1] ==' ) ' )
try{s.Delete(j);
cout << j <<' ' << i << endl;}
catch (OutOfBounds)
{ cout << "No match for right parenthesis" << " at " << i << endl;}
}
// 堆栈中所剩下的 (都是未匹配的
while(!s.IsEmpty()) {
s.Delete(j);
cout << "No match for left parenthesis at " <<j< endl;}
}
void main(void)
{
char expr[MaxLength];
cout << "Type an expression of length at most " << MaxLength << endl;
cin.getline(expr, MaxLength);
cout <<"The pairs of matching parentheses in" << endl;
puts (expr);
cout <<"are" << endl;
PrintMatcnedPairs(expr);
}
输出结果: