C++ STL(六)容器_deque
deque(双端队列):是一种优化了的、对序列两端元素进行添加和删除操作的基本序列容器。
它允许较为快速地随机访问,但它不像vector 把所有的对象保存在一块连续的内存块,而是采用多个连续的存储块,并且在一个映射结构中保存对这些块及其顺序的跟踪.
向deque 两端添加或删除元素的开销很小。它不需要重新分配空间.
所需头文件:#include<deque>
构造函数:
1 deque<int> dA; //构造个空的deque 2 deque<int> dB(5); //定义有5个int元素的deque (dB={0,0,0,0,0}) 3 deque<int> dC(5,1);//定义有5个int元素的deque,每个元素的值为1 (dC={1,1,1,1,1}) 4 deque<int> dD(dC); //通过dC拷贝构造一个dD (dD={1,1,1,1,1}) 5 int nArray[] = {1,2,3}; 6 int nLeng = sizeof(nArray)/sizeof(int); 7 deque<int> dE(nArray, nArray+nLeng); //通过数组拷贝构造一个dE (dE={1,2,3}) 8 //使用迭代器构造 9 deque<int> dd; 10 dd.push_back(1); 11 dd.push_back(2); 12 dd.push_back(3); 13 dd.push_back(4); 14 dd.push_back(5); 15 deque<int> dIt(dd.begin(),dd.end()); //正向迭代器方式构造deque (dIt={1,2,3,4,5}) 16 deque<int> dRit(dd.rbegin(), dd.rend()); //反向迭代器方式构造deque (dRit={5,4,3,2,1}) 17 18 //注意: 19 //begin()与end()配套使用. 正向迭代器 20 //rbegin()与rend()配套使用. 反向迭代器 21 //begin()返回指向deque第一个元素的迭代器 end()返回指向deque最后一个元素+1位置的迭代器 22 //rbegin()返回指向deque最后一个元素的迭代器 rend()返回指向deque第一个元素-1位置的迭代器 23 24 return;
获取大小:
empty() 返回deque是否为空
size() 返回deque大小
max_size() 返回deque所能存储的最大元素个数,这是由系统自动定义的值
resize() 重新设置size,如果变长,变长的元素部份使用默认值,变短就删除多余的元素
注意:deque没有vector中的capacity和reserve方法
1 deque<int> dA; 2 bool bEmpty = dA.empty(); //bEmpty = true 是否为空 3 dA.push_back(1); 4 dA.push_back(2); 5 bEmpty = dA.empty(); //bEmpty = false 6 int nLeng = dA.size(); //nLeng = 2 容器大小 7 int nMaxSize = dA.max_size(); //nMaxSize = 1073741823 所能存储的最大元素个数,这是由系统自动定义的值 8 9 //resize重新设置size,如果变长,变长的元素部份使用默认值,变短就删除多余的元素. 10 dA.resize(10); 11 nLeng = dA.size(); //nLeng = 10 12 dA.resize(1); 13 nLeng = dA.size(); //nLeng = 1 14 15 //注意:deque没有vector中的capacity和reserve方法 16 return;
赋值操作:
数组[]和at()方式赋值
1 //使用数组[]和at()方式赋值 2 deque<int> dA(2); 3 dA[0] = 10; //dA = {10,0} 4 dA.at(1) = 11; //dA = {10,11} 5 6 //使用assign()方式赋值 7 deque<int> dC; 8 //void assign(size_type _Count, const _Ty& _dAl) 9 dC.assign(2,6); //给dC赋值二个int型元素,元素值为6 (dC={6,6}) 10 //void assign(_Iter _First, _Iter _Last) 11 deque<int> dD; 12 dC.assign(dD.begin(),dD.end()); //使用迭代器方式把dD中所有元素赋值给dC (dC={}) 13 14 //使用swap()交换方式赋值 15 deque<int> dE(2,3); 16 deque<int> dF(4,4); 17 dE.swap(dF); //dE = {4,4,4,4} dF = {3,3}
assign()方式赋值
1 //使用assign()方式赋值 2 deque<int> dC; 3 //void assign(size_type _Count, const _Ty& _dAl) 4 dC.assign(2,6); //给dC赋值二个int型元素,元素值为6 (dC={6,6}) 5 //void assign(_Iter _First, _Iter _Last) 6 deque<int> dD; 7 dC.assign(dD.begin(),dD.end()); //使用迭代器方式把dD中所有元素赋值给dC (dC={}) 8 9 //使用swap()交换方式赋值 10 deque<int> dE(2,3); 11 deque<int> dF(4,4); 12 dE.swap(dF); //dE = {4,4,4,4} dF = {3,3}
增加元素操作:
push_front() 往deque头部插入一个元素
push_back() 往deque末尾插入一个元素
insert() 往deque任意位置插入一个元素,指定位置或者指定区间进行插入,第一个参数都是个迭代器。返回值是指向新元素的迭代器
1 deque<int> dA; 2 //使用push_front()方式,头部插入元素 3 dA.push_front(1); //dA = {1} 4 //使用push_back()方式,末尾插入元素 5 dA.push_back(2); //dA = {1,2} 6 7 //使用insert()方式插入元素, 第一个参数都是迭代器,返回值是指向新元素的迭代器 8 deque<int>::iterator it; 9 //iterator insert(const_iterator _Where, const _Ty& _dAl) 指定位置插入 10 it = dA.insert(dA.begin(),2); //往begin()之前插入一个int元素2 (dA={2,1,2}) 此时it指向第一个元素2 11 //void insert(const_iterator _Where, size_type _Count, const _Ty& _dAl) 指定位置插入 12 it = dA.insert(dA.end(),2,3);//往end()之前插入2个int元素3 (dA={2,1,2,3,3}) 此时it指向最后一个元素3 13 //void insert(const_iterator _Where, _Iter _First, _Iter _Last) 指定区间插入 14 deque<int> vB(3,6); 15 it = dA.insert(dA.end(),vB.begin(),vB.end()); //把vB中所有元素插入到dA的end()之前 (dA={2,1,2,3,3,6,6,6}) 16 //此时*it=6,指向最后一个元素值为6的元素位置
删除元素操作:
pop_front() 从deque头部删除一个元素
pop_back() 从deque末尾删除一个元素
erase() 从deque任意位置删除一个元素,指定位置或者指定区间进行删除,第一个参数都是个迭代器。返回值是指向删除后的下一个元素的迭代器
clear() 清除deque中所有元素, size=0
1 deque<int> dA; 2 dA.push_back(1); 3 dA.push_back(2); 4 dA.push_back(3); 5 dA.push_back(4); 6 dA.push_back(5); 7 //使用pop_front()方式删除头部元素 8 dA.pop_front(); //dA={2,3,4,5} 9 //使用pop_back()方式删除末尾元素 10 dA.pop_back(); //dA={2,3,4} 11 //使用erase()方式删除元素,第一个参数都是迭代器,返回值是指向删除后的下一个元素的迭代器 12 deque<int>::iterator it; 13 //iterator erase(const_iterator _Where) 指定位置删除 14 it = dA.erase(dA.begin()); //删除Where位置的元素 (dA={3,4}) 此时it指向元素3 15 //void _Reverse(pointer _First, pointer _Last) 指定区间删除 16 it = dA.erase(dA.begin(),dA.end()); //把begin()到end()之间的所有元素删除 (dA={}) 17 //此时deque中己经没有元素了,迭代器指向的下一个元素就是end() 18 19 //使用clear()方式清除所有元素,size变为0 20 deque<int> dB(5,5); 21 dB.clear(); //(dB={},size=0) 22 23 return;
遍历元素操作:
数组方式、迭代器方式
1 deque<int> dd; 2 dd.push_back(1); 3 dd.push_back(2); 4 dd.push_back(3); 5 dd.push_back(4); 6 dd.push_back(5); 7 8 //使用数组方式正向遍历 9 for (size_t i = 0; i<dd.size(); ++i) 10 { 11 cout<<dd[i]<<" "; 12 } 13 cout<<endl; 14 //使用数组方式反向遍历 15 for (size_t i = dd.size()-1; (int)i>=0; --i) 16 { 17 cout<<dd[i]<<" "; 18 } 19 cout<<endl; 20 //使用正向迭代器方式遍历 21 deque<int>::iterator it; 22 it = dd.begin(); 23 for (it; it!=dd.end(); ++it) 24 { 25 cout<<*it<<" "; 26 } 27 cout<<endl; 28 //使用反向迭代器方式遍历 29 deque<int>::reverse_iterator rit; 30 rit = dd.rbegin(); 31 for (rit; rit!=dd.rend(); ++rit) 32 { 33 cout<<*rit<<" "; 34 } 35 36 return;
释放内存操作:
注意:除了vector以外,其它容器使用clear都会自动释放内存,不需要使用空的容器进行swap
小练习题:
回文检测,检测字符串是否是一个回文(字符串首字母和尾字母必须相同)
1 //回文检测,检测字符串是否是一个回文(字符串首字母和尾字母必须相同) 2 char szStr[] = "Hello,word"; 3 char szStrTwo[] = "MooM"; 4 deque<char> dStr; 5 int nLeng = sizeof(szStr)/sizeof(char); 6 //字符数组默认会添加一个'\0',这里需要少拷贝数组尾部成员 7 dStr.assign(szStr, szStr+nLeng-1); 8 if(dStr.front() == dStr.back()) 9 { 10 printf("%s:是回文\r\n",szStr); 11 } 12 else 13 { 14 printf("%s:不是回文\r\n",szStr); 15 } 16 17 nLeng = sizeof(szStrTwo)/sizeof(char); 18 dStr.assign(szStrTwo,szStrTwo+nLeng-1); 19 if(dStr.front() == dStr.back()) 20 { 21 printf("%s:是回文\r\n",szStrTwo); 22 } 23 else 24 { 25 printf("%s:不是回文\r\n",szStrTwo); 26 } 27 //输出: 28 //Hello,word:不是回文 29 //MooM:是回文 30 getchar(); 31 return;