數據結構系列文章 |
---|
數據結構圖文解析之:數組、單鏈表、雙鏈表介紹及C++模板實現 |
數據結構圖文解析之:棧的簡介及C++模板實現 |
數據結構圖文解析之:隊列詳解與C++模板實現 |
數據結構圖文解析之:樹的簡介及二叉排序樹C++模板實現. |
數據結構圖文解析之:AVL樹詳解及C++模板實現 |
數據結構圖文解析之:二叉堆詳解及C++模板實現 |
數據結構圖文解析之:哈夫曼樹與哈夫曼編碼詳解及C++模板實現 |
棧(Stack)是一種線性存儲結構,它具備以下特色:html
棧的相關概念:node
例如咱們有一個存儲整型元素的棧,咱們依次壓棧:{1,2,3}
git
在壓棧的過程當中,棧頂的位置一直在」向上「移動,而棧底是固定不變的。
若是咱們要把棧中的元素彈出來:
github
出棧的順序爲三、二、1 ,順序與入棧時相反,這就是所謂的」先入後出「。
在彈棧的過程當中,棧頂位置一直在」向下「移動,而棧底一直保持不變。數組
若是你玩過一種稱爲漢諾塔的益智玩具,你就會知道遊戲中小圓盤的存取就是一種先進後出的順序,一個圓柱就是一個棧:
數據結構
棧的經常使用操做爲:測試
棧既然是一種線性結構,就可以以數組或鏈表(單向鏈表、雙向鏈表或循環鏈表)做爲底層數據結構。
本文咱們以數組、單向鏈表爲底層數據結構構建棧。編碼
當以數組爲底層數據結構時,一般以數組頭爲棧底,數組頭到數組尾爲棧頂的生長方向:
3d
棧提供瞭如上所述操做的相應接口。指針
template<typename T> class ArrayStack { public: ArrayStack(int s = 10); //默認的棧容量爲10 ~ArrayStack(); public: T top(); //獲取棧頂元素 void push(T t); //壓棧操做 T pop(); //彈棧操做 bool isEmpty(); //判空操做 int size(); //求棧的大小 private: int count; //棧的元素數量 int capacity; //棧的容量 T * array; //底層爲數組 };
棧的實現仍是相對簡單的,很容易理解。這裏就再也不多此一舉了。
/*棧的判空操做*/ template <typename T> bool ArrayStack<T>::isEmpty() { return count == 0; //棧元素爲0時爲棧空 }; /*返回棧的大小*/ template <typename T> int ArrayStack<T>::size() { return count; }; /*插入元素*/ template <typename T> void ArrayStack<T>::push(T t) { if (count != capacity) //先判斷是否棧滿 { array[count++] = t; } }; /*彈棧*/ template <typename T> T ArrayStack<T>::pop() { if (count != 0) //先判斷是不是空棧 { return array[--count]; } }; /*獲取棧頂元素*/ template <typename T> T ArrayStack<T>::top() { if (count != 0) { return array[count - 1]; } };
int _tmain(int argc, _TCHAR* argv[]) { ArrayStack <int> p(5); for (int i = 0; i < 5; i++) { p.push(i); } cout << "棧的大小:"<<p.size() << endl; cout << "棧是否爲空:"<<p.isEmpty() << endl; cout << "棧頂元素:"<<p.top() << endl; cout << "依次出棧:" << endl; while (!p.isEmpty()) { cout << p.pop() << endl; } getchar(); return 0; }
測試結果:
棧的大小:5 棧是否爲空:0 棧頂元素:4 依次出棧: 4 3 2 1 0
以鏈表爲底層的數據結構時,以鏈表頭爲做爲棧頂較爲合適,這樣方便節點的插入與刪除。壓棧產生的新節點將一直出如今鏈表的頭部;
/*鏈表節點結構*/ template <typename T> struct Node { Node(T t) :value(t), next(nullptr){}; Node() :next(nullptr){}; public: T value; Node<T>* next; };
基於鏈表的棧提供的接口與基於數組的棧一致。
/*棧的抽象數據結構*/ template <typename T> class LinkStack { public: LinkStack(); ~LinkStack(); public: bool isEmpty(); int size(); void push(T t); T pop(); T top(); private: Node<T>* phead; int count; };
/*返回棧的大小*/ template <typename T> int LinkStack<T>::size() { return count; }; /*棧的判空操做*/ template <typename T> bool LinkStack<T>::isEmpty() { return count == 0; }; /*插入元素*/ template<typename T> void LinkStack<T>::push(T t) { Node <T> *pnode = new Node<T>(t); pnode->next = phead->next; phead->next = pnode; count++; }; /*彈棧*/ template <typename T> T LinkStack<T>::pop() { if (phead->next != nullptr) //棧空判斷 { Node<T>* pdel = phead->next; phead->next = phead->next->next; T value = pdel->value; delete pdel; count--; return value; } }; /*獲取棧頂元素*/ template <typename T> T LinkStack<T>::top() { if (phead->next!=nullptr) return phead->next->value; };
int _tmain(int argc, _TCHAR* argv[]) { LinkStack <string> lstack; lstack.push("hello"); lstack.push("to"); lstack.push("you!"); cout << "棧的大小:" << lstack.size() << endl; cout <<"棧頂元素:"<< lstack.top() << endl; while (!lstack.isEmpty()) { lstack.pop(); } cout << "棧的大小:" << lstack.size() << endl; getchar(); return 0; }
測試結果:
棧的大小:3 棧頂元素:you! 棧的大小:0
基於數組的棧: https://github.com/huanzheWu/Data-Structure/blob/master/Stack/Main/Main/ArrayStack.h
基於單鏈表的棧:https://github.com/huanzheWu/Data-Structure/blob/master/singleList/singleList/singleList.h
原創文章,轉載請註明出處:http://www.cnblogs.com/QG-whz/p/5170418.html