數據結構基礎(13) --鏈式棧的設計與實現

採用鏈式存儲的棧成爲鏈式棧(或簡稱鏈棧), 鏈棧的優點是便於多個棧共享存儲空間和提高其效率, 且不存在棧滿上溢的情況(因爲鏈棧是靠指針鏈接到一起,只要內存夠大, 則鏈棧理論上可以存儲的元素是沒有上限的);

    與順序棧相比, 由於順序棧是採用的數組實現, 因此一旦數組填滿, 則必須重新申請內存, 並將所有元素”搬家”, 而鏈棧則省略了這一”耗時耗力”的工作, 但卻需要付出附加一個指針的代價;

    鏈棧通常採用單鏈表實現, 並規定所有的操作都必須實在單鏈表的表頭進行, 而且w我們的鏈棧沒有頭結點, m_top直接指向棧頂元素;

鏈式棧的圖示如下:


鏈棧節點構造:

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. template <typename Type>  
  2. class ChainNode  
  3. {  
  4.     template <typename T>  
  5.     friend ostream &operator<<(ostream &os, const LinkStack<T> &stack);  
  6.     friend class LinkStack<Type>;  
  7. private:  
  8.     ChainNode(const Type &_data, ChainNode *_next = NULL)  
  9.         :data(_data), next(_next) {}  
  10.   
  11.     Type data;  
  12.     ChainNode *next;  
  13. };  

鏈棧設計:

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. template <typename Type>  
  2. class LinkStack  
  3. {  
  4.     template <typename T>  
  5.     friend ostream &operator<<(ostream &os, const LinkStack<T> &stack);  
  6. public:  
  7.     LinkStack(): m_top(NULL) {}  
  8.     ~LinkStack()  
  9.     {  
  10.         makeEmpty();  
  11.     }  
  12.     bool isEmpty() const  
  13.     {  
  14.         return m_top == NULL;  
  15.     }  
  16.   
  17.     void pop() throw(std::out_of_range);  
  18.     const Type &top() const throw(std::out_of_range);  
  19.     void push(const Type &data);  
  20.     void makeEmpty();  
  21.   
  22. private:  
  23.     ChainNode<Type> *m_top;  
  24. };  

棧的三大操作:

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. template <typename Type>  
  2. const Type &LinkStack<Type>::top() const  
  3. throw (std::out_of_range)  
  4. {  
  5.     if (isEmpty())  
  6.         throw std::out_of_range("stack is empty, can`t get data");  
  7.   
  8.     return m_top->data;  
  9. }  
[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. template <typename Type>  
  2. void LinkStack<Type>::pop()  
  3. throw (std::out_of_range)  
  4. {  
  5.     if (isEmpty())  
  6.         throw std::out_of_range("stack is empty, can`t delete");  
  7.   
  8.     ChainNode<Type> *deleteNode = m_top;  
  9.     m_top = m_top->next;  
  10.     delete deleteNode;  
  11. }  
[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. template <typename Type>  
  2. void LinkStack<Type>::push(const Type &data)  
  3. {  
  4.     //此處是整個鏈棧的關鍵點  
  5.     // 該操作會生成一個節點,  
  6.     // 並自動將m_top上移一格,  
  7.     // 而且將m_top原先指向的節點, 作爲新生成的節點的下一節點  
  8.     //注意此處  
  9.     //如果第一次運行push, 則原m_top爲NULL  
  10.     // 新m_top指向第一個元素  
  11.     m_top = new ChainNode<Type>(data, m_top);  
  12. }  

清空整個棧:

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. template <typename Type>  
  2. void LinkStack<Type>::makeEmpty()  
  3. {  
  4.     while (!isEmpty())  
  5.     {  
  6.         pop();  
  7.     }  
  8. }  

輸出棧內所有內容:

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. template <typename Type>  
  2. ostream &operator<<(ostream &os, const LinkStack<Type> &stack)  
  3. {  
  4.     ChainNode<Type> *currentNode = stack.m_top;  
  5.     while (currentNode != NULL)  
  6.     {  
  7.         cout << currentNode->data << ' ';  
  8.         currentNode = currentNode->next;  
  9.     }  
  10.   
  11.     return os;  
  12. }  

測試代碼:

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. int main()  
  2. {  
  3.     LinkStack<int> test;  
  4.     for (int i = 0; i < 10; ++i)  
  5.     {  
  6.         test.push(rand()%100);  
  7.     }  
  8.   
  9.     cout << test << endl;  
  10.     cout << "top = " << test.top() << endl;  
  11.   
  12.     test.pop();  
  13.     cout << "top = " << test.top() << endl;  
  14.   
  15.     test.push(1);  
  16.     cout << "top = " << test.top() << endl;  
  17.   
  18.     while (!test.isEmpty())  
  19.     {  
  20.         test.pop();  
  21.     }  
  22.     cout << test << endl;  
  23.   
  24.     test.push(11);  
  25.     test.push(22);  
  26.     test.push(33);  
  27.     cout << test << endl;  
  28.     test.makeEmpty();  
  29.   
  30.     try  
  31.     {  
  32.         cout << "top = " << test.top() << endl;  
  33.     }  
  34.     catch (const std::exception &e)  
  35.     {  
  36.         cerr << e.what() << endl;  
  37.     }  
  38.   
  39.     return 0;  
  40. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章