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

来源:互联网 发布:外卖软件的好处 编辑:程序博客网 时间:2024/05/17 04:41

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

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

输出结果:

原创粉丝点击