C++ STL容器deque和vector很類似,也是採用動態數組來管理元素。
使用deque之前需包含標頭檔:
#include <deque>
它是定義在命名空間std內的一個class template:
template<class _Ty,
class _Ax = allocator<_Ty> >
class deque;
第一個template參數用來表示元素型別,第二個可有可無,指定記憶體模型。一般使用預設的記憶體模型。
與vector不同的是deque的動態數組首尾都開放,因此能夠在首尾進行快速地插入和刪除操作。
deque的邏輯結構:
deque的內部結構
deque是一種最佳化了的對序列兩端元素進行添加和刪除操作的基本序列容器。通常由一些獨立的區塊組成,第一區塊朝某方向擴充,最後一個區塊朝另一方向擴充。它允許較為快速地隨機訪問但它不像vector一樣把所有對象儲存在一個連續的記憶體塊,而是多個連續的記憶體塊。並且在一個映射結構中儲存對這些塊以及順序的跟蹤。
其內部結構如所示:
deque的特點:
1、支援隨機訪問,即支援[]以及at(),但是效能沒有vector好。
2、可以在內部進行插入和刪除操作,但效能不及list。
deque和vector的不同之處:
1、兩端都能夠快速插入和刪除元素。vector只能在尾端進行。
2、deque的元素存取和迭代器操作會稍微慢一些。因為deque的內部結構會多一個間接過程。
3、迭代器是特殊的智能指標,而不是一般指標。它需要在不同的區塊之間跳轉。
4、deque可以包含更多的元素,其max_size可能更大。因為不止使用一塊記憶體。
5、不支援對容量和記憶體配置時機的控制。
注意:在除了首尾兩端的其他地方插入和刪除元素,都將會導致指向deque元素的任何pointers、references、iterators失效。不過,deque的記憶體重分配優於vector。因為其內部結構顯示不需要複製所有元素。
6、deque的記憶體區塊不再被使用時,會被釋放。deque的記憶體大小是可縮減的。不過,是不是這麼做以及怎麼做由實作版本定義。
deque和vector相似的特性:
1、在中間部分插入和刪除元素相對較慢,因為所有元素都要被移動。
2、迭代器屬於隨即存取迭代器。
最好採用deque的情形:
1、需要在兩端插入和刪除元素。
2、無需引用容器內的元素。
3、要求容器釋放不再使用的元素。
deque的操作函數
建構函式和解構函式:
非變動性操作:
變動性操作:
deque的各項操作只有一下兩點和vector不同:
deque不提供容量操作:capacity()和reverse()。
deque直接提供函數完成首尾元素的插入和刪除。
其他均與vector相同。
注意:
1、除了at()函數,其他成員函數都不會檢查索引或迭代器是否有效。
2、元素的插入和刪除可能會導致記憶體重新分配。所以任何插入或刪除操作都會使所有指向deque元素的pointers、reference、iterators失效。唯一例外的是在首尾插入元素之後,pointers和reference可能仍然有效。
程式樣本:
#include <iostream>#include <deque>#include <string>#include <algorithm>using namespace std;int main(){deque<string> strDeq;strDeq.assign(4,string("CHINA"));strDeq.push_back("first_string");strDeq.push_front("last_string");copy(strDeq.begin(),strDeq.end(),ostream_iterator<string>(cout," "));cout << endl;cout << endl;for(int i = 0;i < strDeq.size();++i)cout << "strDeq[" << i << "] : " << strDeq[i] << endl;cout << endl;for(int i = 0;i < strDeq.size();++i)cout << "strDeq.at(" << i << ") : " << strDeq.at(i) << endl;cout << endl;strDeq.pop_front();strDeq.pop_back();copy(strDeq.begin(),strDeq.end(),ostream_iterator<string>(cout," "));cout << endl;cout << endl;for(int i = 1;i < strDeq.size();++i)strDeq[i] = "pre" + strDeq[i];copy(strDeq.begin(),strDeq.end(),ostream_iterator<string>(cout," "));cout << endl;cout << endl;strDeq.resize(4,"resized string");copy(strDeq.begin(),strDeq.end(),ostream_iterator<string>(cout," "));cout << endl;cout << endl;}
運行結果: