學習筆記--數據結構(之一)堆棧

   堆棧和隊列可能是使用頻率最高的數據結構,這裏主要記錄有關堆棧的一些用法和應用,由於堆棧是一種特殊的線性表,因此可以很自然地從相應的線性表類中派生出堆棧類。

   可以派生出基於公式描述的堆棧類,也可以派生出基於鏈表結構的堆棧類。通過類的派生,可以大大簡化程序設計的任務,但同時代碼的執行效率有明顯損失。由於堆棧是一個很基本的數據結構,許多程序都要用到堆棧,爲了消除程序的額外開銷,可以把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);
}

輸出結果:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章