堆栈的实现
版權聲明:您好,轉載請留下本人博客的地址,謝謝 https://blog.csdn.net/hongbochen1223/article/details/45569033
堆棧,是一種數據結構,其插入和刪除操作都在同一端進行,其中一端稱作棧頂,另外一端稱作棧底。其中,堆棧是一種先進后出的數據結構,既可以使用公式化描述實現,也可以使用鏈表描述進行實現。
例如,我們向棧中插入元素10,20.30,則從棧頂向棧底排列分別為30,20,10,則彈出的時候,分別以30,20,10的順序彈出,在這篇中,先使用公式化描述和鏈表實現堆棧,在后面將學習幾個使用堆棧的比較典型的例子,其中包括括號匹配,漢諾塔,火車重排,離線等價類,迷宮等問題。
好了,話不多說,堆棧的實現還是比較簡單的,下面附上我的代碼:
首先使用公式化描述實現的堆棧:
/*** 堆棧是一個線性表,其插入和刪除操作都在同一端進行* 其中一端成為棧頂,另一端成為棧底** 堆棧是一種先進后出或者是后進先出的數據結構* 可以使用公式化描述實現堆棧,也可以使用鏈表實現堆棧**/ #include "Exception.h" #include <iostream>using namespace std;/*** 適用公式化描述實現LinearStack*/ template<class T> class LinearStack{ public:LinearStack(int MaxLinearStackSize = 10);~LinearStack(){delete [] stack;}bool isEmpty() const{return top == -1;} //返回棧是否為空bool isFull() const{return top == MaxTop;} //棧是否已滿T Top() const; //獲取棧頂元素LinearStack<T>& Add(const T& x); //向棧中添加一個元素LinearStack<T>& Delete(T& x); //從棧中刪除一個元素int Size() const; //獲取堆棧的大小LinearStack<T>& Add(T array[],int addedSize); //輸入一個堆棧void print(); //輸出堆棧中的數據private:int top; //棧頂int MaxTop; //棧的最大容量T *stack; };template <class T> LinearStack<T>::LinearStack(int MaxLinearStackSize){MaxTop = MaxLinearStackSize - 1;top = -1;stack = new T[MaxLinearStackSize]; }template<class T> T LinearStack<T>::Top() const{if(isEmpty()) throw OutOfBounds();else return stack[top]; }template<class T> LinearStack<T>& LinearStack<T>::Add(const T& x){if(isFull()) throw OutOfBounds();top ++;stack[top] = x;return *this; }template<class T> LinearStack<T>& LinearStack<T>::Delete(T& x){if(isEmpty()) throw OutOfBounds();x = stack[top--];return *this; }template<class T> int LinearStack<T>::Size() const{int size = top+1;return size; }template<class T> LinearStack<T>& LinearStack<T>::Add(T array[],int addedSize){int size = this->Size();int left = MaxTop + 1 - size;if(left < addedSize)throw OutOfBounds();for(int i = 0;i < addedSize;i++){this->Add(array[i]);}return *this; }template<class T> void LinearStack<T>::print(){int size = this->Size();for(int i = size-1;i >= 0;i--){cout << stack[i] << " ";}cout << endl; }下面一個是使用鏈表實現的堆棧:
/** LinkedStack.cpp** Created on: 2015年5月7日* Author: 洪波*/#include "Exception.h" #include <iostream>using namespace std;template<class T> class LinkedStack;template<class T> class Node{ friend class LinkedStack<T>;private:T data;Node<T> *link; };template<class T> class LinkedStack{ public:LinkedStack(){top = 0;}~LinkedStack();bool IsEmpty() const{return top == 0;}bool IsFull() const;T Top() const;LinkedStack<T>& Add(const T& x);LinkedStack<T>& Delete(T& x);void print();private:Node<T> *top; //指向棧頂節點 };template<class T> LinkedStack<T>::~LinkedStack(){Node<T> *next;while(top){next = top->link;delete top;top = next;} }template<class T> bool LinkedStack<T>::IsFull() const{try{Node<T> *p = new Node<T>();delete p;return false;}catch(NoMem &nm){return true;} }template<class T> T LinkedStack<T>::Top() const{return top->data; }template<class T> LinkedStack<T>& LinkedStack<T>::Add(const T& x){Node<T> *node = new Node<T>();node->data = x;node->link = top;top = node;return *this; }template<class T> LinkedStack<T>& LinkedStack<T>::Delete(T& x){if(IsEmpty()) throw OutOfBounds();Node<T> *p = top;x = top->data;top = top->link;delete p;return *this; }template<class T> void LinkedStack<T>::print(){Node<T> *p = top;while(p){cout << p->data << " ";p = p->link;}cout << endl; }下面是我的測試類:
/** Test.cpp** Created on: 2015年5月7日* Author: 洪波*/ #include "LinearStack.cpp" #include "LinkedStack.cpp"int main(){/*********************************************** 測試 LinearStack ***********************************************/ // LinearStack<int> ls(10); // // ls.Add(10); // ls.Add(20); // // // ls.print(); // // int array[3] = {30,40,50}; // // ls.Add(array,3); // // ls.print();/*====================================================*//*********************************************** 測試 LinkedStack ***********************************************/LinkedStack<int> linkedS;linkedS.Add(10);linkedS.Add(20);linkedS.print();int n;linkedS.Delete(n);cout << n << endl;return 0; }其中,頭文件”Exception.h”在我之前數據結構和算法的代碼中有。堆棧在平常使用中用的還是挺多的。但相對來說其實現方式還是比較簡單的,其插入和刪除操作的時間復雜度都是O(1),即壓棧和彈出的時間復雜度都是O(1)。效率還是蠻高的。
向程序運行過程中,函數的調用,在保存狀態點的時候,都是保存到棧中的。其中比較典型的應用實例就是火車重排問題,離線等價類問題,漢諾塔問題,迷宮求解問題,括號匹配問題等。我會將在下面一章節中學習這些實例的實現。
總結
- 上一篇: Ubuntu下安装node canvas
- 下一篇: js == ===