前面我们已经充分了解deque的基本知识以及访问方式,本节将一口气为读者详细介绍如何对deque进行增删操作,加快我们的学习进度。这里可以类比vector的增删操作,《vector容器怎么在指定位置前插入元素?》《vector容器怎么删除元素呢?》,读者通过对比学习,总结归纳出自己的宝贵经验,提高对STL容器的掌控力。

我们先谈谈“增”这个操作:

对比vector,我们都知道deque能够实现头增尾增push_front()、push_back();C++11后,deque还能通过emplace_front()、emplace_back()进行头增尾增。相比于前者,后者是直接在内存上构造,省去了相比前者的移动函数、拷贝函数、析构函数这些冗杂过程,提高了元素添加效率。当然,我们也可以指定位置添加元素,如insert()、emplace(),通过位置迭代器添加元素,值得注意的是除insert()外其他添加函数都只能添加一个元素。类比vector的push_back()和emplace_back(),deque对于指定位置添加元素来说,emplace是直接构造,效率高于insert()。那我们通过代码来学习如何为deque增加元素:

#include<bits/stdc++.h>
#include<deque>
/* 如何为deque容器添加元素 */
using namespace std;
/*通过push_back()、push_front()、emplace_back()、emplace_front()为deque添加单个元素*/ 
void test1()
{
/*只能添加单个元素*/
deque<int> dq{1,2,3,4,5};
dq.push_back(0) ;//尾增法 
cout << "push_back()在dq容器尾部添加0后输出所有元素: ";
for(int i=0;i<dq.size();++i) cout << dq[i]<<" ";
cout<<'\n' ;
dq.push_front(0) ;//头增法 
cout << "push_front()在dq容器首部添加0后输出所有元素: ";
for(int i=0;i<dq.size();++i) cout << dq[i]<<" ";
cout << '\n';
dq.emplace_back(0) ;//尾增法 
cout << "push_emplace()在dq容器尾部添加0后输出所有元素: ";
for(int i=0;i<dq.size();++i) cout << dq[i]<<" ";
cout<<'\n' ;
dq.push_front(0) ;//头增法 
cout << "emplace_front()在dq容器首部添加0后输出所有元素: ";
for(int i=0;i<dq.size();++i) cout << dq[i]<<" ";
cout << '\n';
cout << '\n';
} 
/*通过insert()、empplace()为deque添加单个或多个元素*/ 
void test2()
{
deque<int> dq{1,2,3,4,5};
/*insert()*/
dq.insert(dq.begin()+2,0) ;//单个添加 
cout << "insert()在第三个元素前添加0后输出所有元素: ";
for(int i=0;i<dq.size();++i) cout << dq[i]<<" ";
cout<<'\n' ;
dq.insert(dq.begin()+2,{9,9,9}) ;//多个添加 
cout << "insert()在第三个元素前添加{9,9,9}后输出所有元素: ";
for(int i=0;i<dq.size();++i) cout << dq[i]<<" ";
cout << '\n';
dq.insert(dq.begin()+2,3,7) ;//n个体的方式添加 
cout << "insert()在第三个元素前添加3个7后输出所有元素: ";
for(int i=0;i<dq.size();++i) cout << dq[i]<<" ";
cout << '\n';
dq.clear();//清空元素,重新测试emplace 
/*emplace()且只能添加单个元素*/
dq={1,2,3,4,5};//'='重载实现直接赋值
dq.insert(dq.begin()+2,0) ;//只能添加单个元素 
cout << "emplace()在第三个元素前添加0后输出所有元素: ";
for(int i=0;i<dq.size();++i) cout << dq[i]<<" ";
cout << '\n';
}
int main(){
    test1();
    test2();
    return 0;
}

编译后结果为:

成功添加元素

通过代码我们知道,头增尾增只能添加单个元素;指定位置添加元素时,insert()可多个添加,emplace()只能单个添加。

我们再谈谈“减”这个操作:

对比vector,我们都知道deque能够实现头删尾删pop_front()、pop_back();指定位置删除元素erase(),清空容器是clear()。这里重点讲解erase()。对于erase() 来说,参数如果是一个位置迭代器,则删除该位置元素;如果是两个位置迭代器,则删除该区间位置。

话不多说,上代码:

#include<bits/stdc++.h>
#include<deque>
/* 如何为deque容器删除元素 */
using namespace std;
/*重点讲解:通过erase()为deque删除元素*/ 
void test1()
{
/*erase()*/
deque<int> dq{1,2,3,4,5,7,8,9,10};
dq.erase(dq.begin()+2) ;//参数为1个位置迭代器,删除第3个元素 
cout << "erase(dq.begin()+2)在dq容器内删除第3个元素后输出所有元素: ";
for(int i=0;i<dq.size();++i) cout << dq[i]<<" ";
cout<<'\n' ;
dq.erase(dq.begin()+4,dq.begin()+6) ;//参数为两个迭代器,删除该区间[ begin()+4,begin()+6)所有元素 
cout << "erase(begin()+4,begin()+6)在dq容器内删除该区间[ 5,7)所有元素后输出所有元素: ";
for(int i=0;i<dq.size();++i) cout << dq[i]<<" ";
cout << '\n';
cout << '\n';
} 
/*练习头删尾删和clear()全清空*/ 
void test2()
{
deque<int> dq{1,2,3,4,5};
/*pop首尾元素*/
dq.pop_front() ;//头删 
cout << "pop_front()删除第一个元素后输出所有元素: ";
for(int i=0;i<dq.size();++i) cout << dq[i]<<" ";
cout<<'\n' ;
dq.pop_back() ;//尾删
cout << "pop_back()删除最后一个元素后输出所有元素: ";
for(int i=0;i<dq.size();++i) cout << dq[i]<<" ";
cout<<'\n' ;
 /*clear()一键清空*/
 dq.clear() ;
cout << "clear()后dq.size()为:"<< dq.size()<<'\n';
cout<<'\n' ;
}
 
int main(){
    test1();
   test2();
    return 0;
}

结果也是不出所料,都能按我们的指令实现元素删除:

删除deque内元素

你以为这就结束了?我这里有一个erase的妙用。大家都知道remove()吧,remove(pos1,pos2,T)里前面两个参数都是位置迭代器,第三个参数T是一个容器内元素,该函数的核心是在覆盖掉区间里的所有T,然后返回该区间内第一个无效内存的位置迭代器。

比如我们有这样一个deque:

{1,2,3,4,5}

如果我们调用remove(dq.begin(),dq.end(),3),容器内会发生这样一个情况:

{1,2,4,5,5}

没错,3被覆盖了,此时remove函数返回迭代器dq.begin()+3,也就是倒数第二个5的位置,此时配合dq.erase(|remove(dq.begin(),dq.end(),3),|dq.end())就能清空dq容器里所有的3了(这里'|'是为了方便观察函数参数)。

问题来了,想要删除deque容器{1,2,3,4,3,5,3,6,3,7}里所有的3,你会怎么做?

#include<bits/stdc++.h>
#include<deque>
/* 删除deque容器{1,2,3,4,3,5,3,6,3,7}里所有的3 */
using namespace std;
void test()
{
/*erase()+remove()*/
deque<int> dq{1,2,3,4,3,5,3,6,3,7};
dq.erase(remove(dq.begin(),dq.end(),3),dq.end()); 
cout <<"删除deque容器{1,2,3,4,3,5,3,6,3,7}里所有的3后遍历容器: " ;
for(int i=0;i<dq.size();++i) cout << dq[i] << " ";
} 
 
int main(){
    test();
    return 0;
}

结果为:

remove()配合deque.erase()

也是完成指定元素全清工作,这个remove()+erase()小技巧,你回了吗?

总结:本节详细讲解了deque的增删操作,内容量大管饱,希望对您的提升有帮助。


点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)