[STL]deque和stack、queue

      怎麼說呢,deque是一種雙向開口的連續線性空間,至少邏輯上看上去是這樣。然而事實上卻沒有那麼簡單,準確來講deque實際上是一種分段連續空間,所以其實現以及各類操做比vector複雜的多。前端

 

一.deque的中控器node

      deque是有一段一段的定量連續空間構成,採用一塊所謂的map(固然不是map容器)做爲主控。map是一小塊連續空間,其中每個元素都是一個指針,指向另外一段連續性空間(緩衝區)。緩衝區纔是deque的儲存空間主體。咱們能夠指定緩衝區大小,默認值0表示使用512字節緩衝區。deque設計結構以下圖所示:後端

 

二.deque的數據結構數據結構

      deque除了維護map的指針外,也要維護startfinish兩個迭代器,分別指向第一緩衝區的第一個元素和最後緩衝區的最後一個元素(的下一個位置)。此外,它還要記錄當前map的大小,由於當map結點不夠的時候,須要另外配置一個更大的map,計算其大小須要知道當前map的大小(源碼爲:new_map_size=map_size+max(map_size,nodes_to_add)+2;)。deque數據結構以下:函數

class deque
{
public:
	typedef T value_type;
	typedef valude_type *pointer;
	typedef size_f size_type;
public: //迭代器
	typedef __deque_iterator<T,T&,T*,BufSiz> iterator;
protected: //元素的指針的指針
	typedef pointer *map_pointer;
protected: 
	iterator start; 
	iterator finish;
	map_pointer map;
	size_type map_size; //map中指針個數
...
};

 

三.deque的成員函數spa

      考慮到deque的特殊結構,因此實現deque的各類操做都至關瑣碎複雜。最關鍵的就是判斷是否已經處於緩衝區邊緣,若是是,一旦前進或後退就必須跳躍至下一個或上一個緩衝區。還有一個重要問題就是當map前端或尾端備用空間不足時就要從新配置新map(配置更大的,拷貝原來的,釋放原來的),下面的push_back()和push_front()等函數都須要先判斷。下面分別解釋deque的各個成員函數。設計

  • push_back():當最後緩衝區有兩個(含)以上的空間,直接在緩衝區增長新元素;當最後緩衝區只剩一個備用空間時,push_back()調用push_back_aux(),先配置一個新的緩衝區,而後再在那個僅剩的備用空間定義新元素,並更改finish的狀態,令其指向新結點。
  • push_front():當第一緩衝區有備用空間時,直接在備用空間增長新元素;當第一緩衝區無備用空間時,調用push_front_aux()配置新結點(緩衝區),增長新元素,並改變start狀態。
  • pop_back():當最後緩衝區有一個(含)以上元素,就將finish向前移一位並將最後那個元素析構掉;當最後緩衝區沒有任何元素,就調用push_pop_aux()將這個緩衝區釋放。解釋一下:第一種狀況finish指向最後緩衝區的first位置,第二種狀況finish指向最後第二個緩衝區的last位置。
  • pop_front():第一緩衝區有兩個(含)以上元素,將第一個元素析構,將start後移;不然,將這個緩衝區釋放,start指向下一個緩衝區第一個元素。
  • clear():deque的最初狀態(即無任何元素時)保有一個緩衝區,所以clear()以後也同樣要保留一個緩衝區,finish=start。
  • erase():先判斷清除空間先後元素個數,移動較少一端
  • insert():若在最前端,即push_front(),最後端相似;判斷插入點先後元素個數,移動較少的一端

 

四.配接器stack和queue指針

      stack是一種先進後出(FILO)的數據結構,它只有一個出口。deque是雙向開口的數據結構,因此SGI STL便以deque做爲缺省狀況下的stack底部結構,封閉其頭端開口。stack沒有迭代器,因此除了頂部元素,沒法存取其它元素,即不能遍歷stack。blog

      stack的成員函數都是針對其頂部元素進行操做:push(),pop(),top()。源碼

      queue是一種先進先出(FIFO)的數據結構,它有兩個出口。queue也是以deque做爲底部結構,封閉其底端的出口和前端的入口。queue,只有頂端(兩端)的元素能被外部使用,因此queue也沒有迭代器,不提供遍歷功能。

      queue的成員函數有:front(),back(),push(),pop()。

      能夠看到stack和queue的成員函數以及特性都是針對其數據結構來的,因此深刻理解其內部結構,不易與deque衆多的成員函數混淆。固然stack和queue也能夠list爲底層結構實現。

 

參考:《STL源碼剖析》

相關文章
相關標籤/搜索