SGISTL原始碼閱讀十七 stack(棧)
阿新 • • 發佈:2018-11-14
SGISTL原始碼閱讀十七 stack(棧)
前言
前面我們已經學習了序列式容器vector
,list
和deque
。
本次要進行分析的是stack
,它是一種先進後出(First In Lat Out,FILO)資料結構,在學習資料結構的時候應該都接觸過,在這裡stack
是一個配接器(adapter),它預設以deque
容器作為它的底部結構實現。接下來我們深入原始碼進行學習。
- 配接器
具有這種“修改某物介面,形成另一種風貌”之性質者,稱為adapter
深入原始碼
stack
的定義部分
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES //使用了deque作為它的底層 template <class T, class Sequence = deque<T> > #else //也可指定 template <class T, class Sequence> #endif class stack { //操作符過載,友元函式宣告 friend bool operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&); friend bool operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&); public: //聲明瞭相應型別 //但是我們可以注意到這裡只有4個,stack是沒有迭代器的 typedef typename Sequence::value_type value_type; typedef typename Sequence::size_type size_type; typedef typename Sequence::reference reference; typedef typename Sequence::const_reference const_reference; protected: //預設使用了deque作為底層容器 Sequence c;
通過以上原始碼我們發現stack
並沒有迭代器,但是這一點並不難理解。所有進入stack
的元素都必須滿足FILO,它並不提供遍歷或是其他訪問操作,只能從stack
的頂端pop
出元素或者通過top
獲取頂部的元素。
stack
操作符過載
//過載== template <class T, class Sequence> bool operator==(const stack<T, Sequence>& x, const stack<T, Sequence>& y) { //底層的Sequence相等則兩個stack相等 return x.c == y.c; } //過載<,思想類似過載== template <class T, class Sequence> bool operator<(const stack<T, Sequence>& x, const stack<T, Sequence>& y) { return x.c < y.c; }
stack
提供的介面
stack
所提供的介面也是完全利用了底層容器c來完成操作
public: //判斷stack是否為空 bool empty() const { return c.empty(); } //獲取stack的長度 size_type size() const { return c.size(); } //獲取stack的頂部元素 reference top() { return c.back(); } const_reference top() const { return c.back(); } //將元素壓棧 void push(const value_type& x) { c.push_back(x); } //將元素從頂部彈出 void pop() { c.pop_back(); }
stack
的簡單使用
從原始碼可以看出,stack
預設使用deque
作為它的底層容器,但是也可以指定底層容器。
#include <iostream>
#include <stack>
using namespace std;
int main()
{
//預設使用deque作為底層容器
stack<int> mystack;
mystack.push(6);
mystack.push(2);
mystack.push(5);
mystack.push(0);
cout << "size:" << mystack.size() << endl;
cout << "top element:" << mystack.top() << endl;
mystack.pop();
cout << "top element:" << mystack.top() << endl;
mystack.pop();
cout << "top element:" << mystack.top() << endl;
mystack.pop();
cout << "top element:" << mystack.top() << endl;
mystack.pop();
cout << "size:" << mystack.size() << endl;
return 0;
}
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
int main()
{
//stack<int> mystack;
//指定vector作為底層容器
stack<int, vector<int> > mystack;
mystack.push(6);
mystack.push(2);
mystack.push(5);
mystack.push(0);
cout << "size:" << mystack.size() << endl;
cout << "top element:" << mystack.top() << endl;
mystack.pop();
cout << "top element:" << mystack.top() << endl;
mystack.pop();
cout << "top element:" << mystack.top() << endl;
mystack.pop();
cout << "top element:" << mystack.top() << endl;
mystack.pop();
cout << "size:" << mystack.size() << endl;
return 0;
}
總結
在閱讀STL原始碼之前對stack
可能的資料結構已經比較清楚了,因為它是最最基礎的一個數據結構了。之前也自己實現過stack
,底層無非使用到了陣列和連結串列。
閱讀了STL原始碼發現它只是一個配接器,通過呼叫比它更加底層的容器來進行操作,程式碼也非常地簡單。
我們常把另外一個數據結構和stack
作比較,那就是queue
,一種FIFO的資料結構,我們將在下一篇文章中分析它。