学习笔记--数据结构(之一)堆栈

   堆栈和队列可能是使用频率最高的数据结构,这里主要记录有关堆栈的一些用法和应用,由于堆栈是一种特殊的线性表,因此可以很自然地从相应的线性表类中派生出堆栈类。

   可以派生出基于公式描述的堆栈类,也可以派生出基于链表结构的堆栈类。通过类的派生,可以大大简化程序设计的任务,但同时代码的执行效率有明显损失。由于堆栈是一个很基本的数据结构,许多程序都要用到堆栈,为了消除程序的额外开销,可以把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);
}

输出结果:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值