標籤:style class blog code http tar
說明:本文僅供學習交流,轉載請標明出處,歡迎轉載!
上篇文章STL之容器適配器stack的實現架構已經介紹了STL是如何藉助基礎容器實現一種常用的資料結構stack (棧),本文介紹下另外一種STL內部定義的另外一種STL容器適配器queue(隊列)。
對於接觸過資料結構的人來說,隊列並不陌生,它是一種FIFO(first in first out)的資料結構。與棧相比,隊列的不同之處在於:(1)隊列是一種先進先出的資料結構,而棧則是一種後進先出的資料結構;(2)隊列支援首尾兩端的訪問操作,而棧只支援一端(即頂端)的訪問操作;(3)隊列從隊尾插入,從隊首彈出;而棧的插入和彈出都位於棧頂。當然,容器適配器queue與stack有個共同之處是,兩者都不支援遍曆操作,內部並不提供迭代器。
從上面的對比我們分析我們可以推斷出這兩種適配器對基礎容器的要求是不一樣的,如上面所提到的第(3)點區別:queue的基礎容器必須支援能夠從首部彈出,而stack的基礎容器必須支援尾部彈出。換句話說,queue的基礎容器必須支援pop_front()操作,而stack的基礎容器必須支援pop_back()操作。正因為這一點,順序容器vector、list和deque均可作為stack的基礎容器,而list和deque可作為queue的基礎容器,而vector則不能作為queue的基礎容器(因為vector)不提供pop_front()操作,這兩個適配器的預設基礎容器均為deque。
根據stack和queue操作的區別,我們可以對比分析stack和queue所提供操作的不同。
queue所提供的操作如下:
(1)擷取當前隊列中元素的個數。size_type size(),stack也提供該操作。
(2)擷取隊首元素(不彈出)。T & front(),stack不提供該操作。
(3)擷取隊尾部元素(不彈出)。T & back(),stack對應的函數為T & top()。
(4)入隊操作。void push(const T &t),stack也提供一樣的函數,對應為入棧操作。
(5)出隊操作。void pop(),stack也提供一樣的函數,對應為出棧操作。
(6)判斷隊列是否為空白。bool empty(),stack也提供一樣的函數。
如果想使用STL中定義的queue適配器,需要引用queue標頭檔,#include<queue>。
下面給出queue適配器的實現代碼和測試代碼:
#include<iostream>#include<deque>using namespace std;/****************queque的定義*************/template<class T,class Sequence=deque<T> >class queue{friend bool operator==(const queue& x,const queue& y);friend bool operator<(const queue&x,const queue& y);/****************容器適配器queue公有屬性*********************/public: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:Sequence c;//基礎容器/*************queue的常用操作****************/public:bool empty()const;//判斷是否為空白size_type size()const;//元素個數reference front();//擷取隊首元素const_reference front()const;reference back();//擷取隊尾元素const_reference back()const ;void push(const value_type& x);//進隊列void pop();//出隊操作};/***************queue類外實現***************/template<class T,class Seq>bool queue<T,Seq>::empty()const//判斷隊列是否為空白隊列,const在類外實現的時候也不能省{return c.empty(); }template<class T,class Seq>typename queue<T,Seq>::size_type queue<T,Seq>::size()const//返回隊列內元素的個數{return c.size();}template<class T,class Seq>typename queue<T,Seq>::reference queue<T,Seq>::front()//擷取隊首元素{return c.front();}template<class T,class Seq>typename queue<T,Seq>::const_reference queue<T,Seq>::front()const//返回隊首元素的常引用{return c.front();}template<class T,class Seq>typename queue<T,Seq>::reference queue<T,Seq>::back()//取隊尾元素的引用{return c.back();}template<class T,class Seq>typename queue<T,Seq>::const_reference queue<T,Seq>::back()const//取隊尾元素的引用{return c.back();}template<class T,class Seq>void queue<T,Seq>::push(const value_type& t)//壓隊列{c.push_back(t);}template<class T,class Seq>void queue<T,Seq>::pop()//出隊列{c.pop_front();}int main(){queue<int> q;q.push(1);q.push(2);q.push(3);q.push(4);while(!q.empty()){cout<<"size="<<q.size()<<" ";cout<<q.front()<<endl;q.pop();}return 0;}
參考資料
[1]《STL源碼剖析 侯捷》
[2]《C++Primer 第4版》