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可能仍然有效。
程序示例:
[cpp]
#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;
}
#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;
}
運行結果:
摘自 江南煙雨