c++ 双端队列 deque用法解析

2023-10-27

1、deque的作用

deque即双端队列,它的用法非常强大,可以代替栈stack、队列queue、向量容器vector等等。

因为它能像栈一样后进先出、也能像queue一样先进先出,还能像vector一样随机访问,同时支持sort、lower_bound、reverse等内置函数

但是顾名思义,它的主要功能还是双端队列,可以随时从头添加或删除元素,也可以随时从末尾添加或者删除元素

2、deque的定义

deque的头文件就是deque使用时添加头文件即可

#include<deque>

定义的方式:
deque<储存的类型> 容器名

例如:

deque<int> q;//定义一个储存int类型的双端队列
deque<double> q;//定义一个储存double类型的双端队列
deque<string> q;//定义一个储存string类型的双端队列
deque<自定义结构体> q;//还可以定义一个储存结构体或类的双端队列

当然也可以定义队列数组:

deque<int> q[n];//定义一个储存int类型的双端队列数组
deque<double> q[n];//定义一个储存double类型的双端队列数组
deque<string> q[n];//定义一个储存string类型的双端队列数组
deque<自定义结构体> q[n];//还可以定义一个储存结构体或类的双端队列数组
//n为队列的大小

3、deque的成员函数

//这些都是必会的成员函数
size()//返回返回容器中元素个数
begin()//返回头部迭代器
end()//返回尾部+1迭代器
rbegin()//返回逆首部迭代器
rend()//返回逆尾部-1迭代器
front()//返回首个元素
back()//返回尾部元素
push_front()//在前面添加一个函数
emplace_frontback()//和push_front()是一样的作用
push_back()//在末尾添加一个函数
emplace_back()//和push_back()是一样的作用
pop_front()//弹出第一个个元素
pop_back()//弹出最后一个元素
empty()//判断是否为空
insert()//在指定位置插入元素
erase()//在指定位置删除元素
clear()//清空容器

详细解析:
(1)size()
size()是最常用的成员函数了,常用于deque的遍历和元素个数的查询

(2)push_back()
除了初始化以外,push_front()和push_back()是deque最重要的修改函数了,复杂度为O(1),而insert()的复杂度为O(n),差距明显

(3)front()、back()
查询首元素和未元素,其实通过随机访问,q[0]、q[q.size()-1]是可以达到相同效果的,用front()和back()显得专业点

(4)begin()、end()
通常用来方便排序的,也可以用来遍历,但没必要,通过下标遍历更简单快捷,rbegin()、rend()则可以用来逆序排序

(5)insert()
insert (position, x );
insert (position, n, x );
insert (position, first, last );
插入新的元素,
第一个函数,在迭代器指定的位置前插入值为x的元素
第二个函数,在迭代器指定的位置前插入n个值为x的元素
第三个函数,在迭代器指定的位置前插入另外一个容器的一段序列迭代器first到last
复杂度很高,迫不得已不使用

(6)erase()
erase ( position );
erase (first, last );
删除元素或一段序列
同样地,复杂度很高,迫不得已不使用

示例代码:

#include<iostream>//c++标准输入输出流 
#include<deque>//deque的头文件 
#include<algorithm>//算法头文件,包含大量内置算法 
using namespace std;//std即standard的缩写,使用标准命名空间
void print(auto q){//遍历函数 
	for(auto c:q){
		cout<<c<<' ';
	}
	cout<<endl;
} 
int main(){
	deque<int> q;//定义一个储存int类型的双端队列 
	q.emplace_back(2);
	q.emplace_back(1);//在双端队列末尾添加元素1
	q.emplace_back(2);
	q.emplace_back(3);
	q.emplace_back(6);
	q.emplace_back(7);
	q.emplace_back(8);
	cout<<"现在有的元素:";
	print(q); 
	cout<<endl; 
	
	
	q.pop_front();//弹出首元素 
	cout<<"q.pop_front()弹出第一个元素后,现在有的元素:"; 
	print(q); 
	cout<<endl; 
	
	q.pop_back();//弹出末尾元素 
	cout<<"q.pop_back()弹出末尾元素后,现在有的元素:"; 
	print(q); 
	cout<<endl;
	
	q.emplace_front(4);//在双端队列前添加元素4
	cout<<"q.emplace_front(4)添加元素4后,现在有的元素:"; 
	print(q); 
	cout<<endl; 
	
	q.emplace_back(5);//在双端队列末尾添加元素5
	cout<<"q.emplace_back(5)添加元素5后,现在有的元素:"; 
	print(q); 
	cout<<endl; 
	
	reverse(q.begin(),q.end());//翻转函数 
	cout<<"reverse(q.begin(),q.end())翻转元素后,现在有的元素:"; 
	print(q); 
	cout<<endl; 
	
	sort(q.begin(),q.end());//排序函数 
	cout<<"sort(q.begin(),q.end())排序元素后,现在有的元素:"; 
	print(q); 
	cout<<endl; 
	
	sort(q.rbegin(),q.rend());//排序函数 
	cout<<"sort(q.rbegin(),q.rend())逆序元素后,现在有的元素:"; 
	print(q); 
	cout<<endl; 
	
	q[0]=10;//通过下标更改值
	cout<<"q[0]=10更改q[0]的值后,现在有的元素:"; 
	print(q); 
	cout<<endl; 
	
	q.insert(q.begin()+1,5);//第二个位置插入5 
	cout<<"q.insert(q.begin()+1,5)第二个位置插入5后,现在有的元素:"; 
	print(q); 
	cout<<endl; 
	
	q.insert(q.begin()+1,2,6);//第二个位置插入2个6 
	cout<<"q.insert(q.begin()+1,2,6)第二个位置插入2个6后,现在有的元素:"; 
	print(q); 
	cout<<endl; 
	
	q.erase(q.begin()+1);//删除第2个元素 
	cout<<"q.erase(q.begin()+1)删除第2个元素后,现在有的元素:"; 
	print(q); 
	cout<<endl; 
	
	q.erase(q.begin()+1,q.begin()+2);//删除第2至第3个位置的元素 
	cout<<"q.erase(q.begin()+1,q.begin()+2)删除第2至第3个位置的元素 ,现在有的元素:"; 
	print(q); 
	cout<<endl;
	
	cout<<"目前的q.size()="<<q.size()<<endl<<endl; 
	
	//判断是否非空
	cout<<"q.empty()="<<q.empty()<<",0代表非空,1代表空的"<<endl<<endl; 
	
	q.clear();//清空容器 
	cout<<"q.clear()清空容器后 ,现在有的元素:"; 
	print(q); 
	cout<<endl;
	
	
	cout<<"目前的q.size()="<<q.size()<<endl<<endl; 
	
	//判断是否非空
	cout<<"q.empty()="<<q.empty()<<",0代表非空,1代表空的"<<endl<<endl; 
}

运行结果:

现在有的元素:2 1 2 3 6 7 8

q.pop_front()弹出第一个元素后,现在有的元素:1 2 3 6 7 8

q.pop_back()弹出末尾元素后,现在有的元素:1 2 3 6 7

q.emplace_front(4)添加元素4后,现在有的元素:4 1 2 3 6 7

q.emplace_back(5)添加元素5后,现在有的元素:4 1 2 3 6 7 5

reverse(q.begin(),q.end())翻转元素后,现在有的元素:5 7 6 3 2 1 4

sort(q.begin(),q.end())排序元素后,现在有的元素:1 2 3 4 5 6 7

sort(q.rbegin(),q.rend())逆序元素后,现在有的元素:7 6 5 4 3 2 1

q[0]=10更改q[0]的值后,现在有的元素:10 6 5 4 3 2 1

q.insert(q.begin()+1,5)第二个位置插入5后,现在有的元素:10 5 6 5 4 3 2 1

q.insert(q.begin()+1,2,6)第二个位置插入26后,现在有的元素:10 6 6 5 6 5 4 3 2 1

q.erase(q.begin()+1)删除第2个元素后,现在有的元素:10 6 5 6 5 4 3 2 1

q.erase(q.begin()+1,q.begin()+2)删除第2至第3个位置的元素 ,现在有的元素:10 5 6 5 4 3 2 1

目前的q.size()=8

q.empty()=0,0代表非空,1代表空的

q.clear()清空容器后 ,现在有的元素:

目前的q.size()=0

q.empty()=1,0代表非空,1代表空的

四、deque的遍历

(1)迭代器iterator

代码:

#include<iostream>
#include<deque>
using namespace std;
int main(){
	deque<int> q;//定义 
	q.emplace_back(1);//插入元素1 
	q.emplace_back(3);//插入元素3
	q.emplace_back(2);//插入元素2
	deque<int>::iterator it;//使用迭代器
	for(it=q.begin();it!=q.end();it++){
		cout<<*it<<' ';
	} 
} 

运行结果:

1 3 2

(2)下标遍历

代码:

#include<iostream>
#include<deque>
using namespace std;
int main(){
	deque<int> q;//定义 
	q.emplace_back(1);//插入元素1 
	q.emplace_back(3);//插入元素3
	q.emplace_back(2);//插入元素2
	for(int i=0;i<q.size();i++){
		cout<<q[i]<<' ';
	} 
} 

运行结果:

1 3 2

(3)foreach遍历

代码:

#include<iostream>
#include<deque>
using namespace std;
int main(){
	deque<int> q;//定义 
	q.emplace_back(1);//插入元素1 
	q.emplace_back(3);//插入元素3
	q.emplace_back(2);//插入元素2
	for(int c:q){
		cout<<c<<' ';
	} 
} 

运行结果:

1 3 2

两种逆序遍历:

代码:

#include<iostream>
#include<vector>
using namespace std;
int main(){
	vector<int> q;//定义 
	q.emplace_back(1);//插入元素1 
	q.emplace_back(3);//插入元素3
	q.emplace_back(2);//插入元素2
	
//	迭代器法 
	vector<int>::reverse_iterator it;//使用迭代器
	for(it=q.rbegin();it!=q.rend();it++){
		cout<<*it<<' ';
	} 
	cout<<endl;
	
//	下标遍历法
	for(int i=q.size()-1;i>=0;i--){
		cout<<q[i]<<' ';
	} 
} 

运行结果:

2 3 1
2 3 1

foreach虽然简单易用,但是不支持逆序遍历

有小伙伴发现dev不能编译部分代码,那是因为dev还未支持c++11,可以看这篇文章解决
dev使用c++11教程

是不是很简单呢?

刚接触肯定会觉得难,多些做题多些用,熟悉了就容易了,兄弟萌,加油!!!

文章尚有不足,欢迎大牛们指正

感谢观看,点个赞吧

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++ 双端队列 deque用法解析 的相关文章

随机推荐

  • 14-5 使用 xml 完成布局

    14 3 小节中 helloworld程序创建窗口使用代码创建 此外 也可使用 xml 完成窗口布局 代码仅仅用来处理数据逻辑 实现布局和数据处理相分离 布局的 ui 代码 builder ui
  • JumpServer开源堡垒机安装配置

    JumpServer开源堡垒机安装与配置 一 简介 二 下载与安装 2 1 下载 2 2 安装 2 3 其他 一 简介 JumpServer 堡垒机帮助企业以更安全的方式管控和登录各种类型的资产 支持 官网地址 https www jump
  • windows文件服务器 文件方案,windowsserver2008文件服务器搭建2种方案.docx

    文件服务器搭建的两种方案范光华制作 文件服务器搭建的两种方案范光华制作 文件服务器搭建的两种方案 搭建目的 1 实现企业文件共享与传输 提高工作效率 2 提高企业访问文件的安全性 搭建环境 1 windows server 2008 R2
  • Navicat Premium 安装 & 注册

    Navicat Premium 一 Navicat Premium的安装 1 暂时关闭windows的病毒与威胁防护弄完再开 之后安装打开过程中弹窗所有警告全部允许 不然会被拦住 2 下载安装包 解压 链接 https pan baidu
  • 爬虫抓取图片:下载高质量图片

    目录 1 抓取图片简介 2 准备工作 3 分析Unsplash网站结构 4 编写图片爬虫
  • stm32使用PWM时,关闭PWM引脚会出现高电平解决方案

    现在使用TIM3来产生PWM波形 并通过软件打开 关闭PWM以实现调制波形 做法是 打开 TIM Cmd TIM3 ENABLE 关闭 TIM Cmd TIM3 DISABLE 跟踪到TIM Cmd之后 发现直接操作寄存器就可以了 TIMx
  • 从Random Walk(随机游走)到Graph Embedding(DeepWalk,LINE,Node2vec,SDNE,Graph2vec,GraphGAN)

    前言 本文转载自csdn博主上杉翔二系列博客并外加一些自己收集的资料 在这里仅作为自己学习之用 原文链接 https blog csdn net qq 39388410 article details 87904974 1 随机游走 普通数
  • idea java 插件开发_Intellij IDEA插件开发入门详解

    现今的IDE尽管有如 洪水猛兽 般强大 但要知道再强大的IDE也没法提供给使用者想要的一切功能 所以IDE一般都提供有API接口供开发者自行扩展 下面以Intellij IDEA 12下的插件开发为例 来看一下如何进一步增强IDE以适应开发
  • ROS自学实践(6):ROS进行激光SLAM建图——gmapping

    本节主要记录运行ROS自带的SLAM建模包gmapping方法 为后续理解这些代码 建立自己的SLAM算法打下基础 基于粒子滤波算法 二维栅格地图 需要里程计信息 1 通过命令行安装gmapping包 sudo apt get instal
  • win10下qt 中没有代码提示框了怎么办?

    在这里我也找了好久 发现是跟你装的输入法有冲突了 所以代码提示没有了 请你切换到英文的输入下 把你的输入法换成标准的英文输入输入状态 图片如下 换成这样就可以提示了 如图所示完美解决不能提示的问题 好了完美解决问题 在这里我放上我讲的几个课
  • Elasticsearch搜索详解(六):文本检索

    文本检索是关系型数据库 如 MySQL 的弱项 而恰恰是 ES 的强项 前一篇文章已经提到了 match term 除此之外还有multi match match phrace 等 分别的含义是 match 从一个字段中检索关键字 包括模糊
  • react中setState即时更新解决方案

    博主在做一个前端项目时 需要根据props中的状态来修改state中的状态 由于react中setState更新状态不能及时显示到页面 博主总结如下可及时更新state中的方法 1 componentWillReceiveProps 2 g
  • Mybatis:xml配置和基本增删改查

    目录 一 环境配置 environments 1 事务管理器 transactionManager 2 数据源 dataSource 3 属性 property 4 设置 settings 5 类型别名 typeAliases 二 安装My
  • net.ipv4.tcp_tw_reuse是干嘛的?

    文章目录 前言 准备工作 sd01的配置 sd02的配置 开始测试 关闭net ipv4 tcp tw reuse 打开net ipv4 tcp tw reuse 关闭客户端的net ipv4 tcp timestamps 关闭服务器端的n
  • Nacos+Node基础教程

    简介 Nacos是一个更易于构建云原生应用的动态服务发现 配置管理和服务管理平台 功能 动态配置服务 动态配置服务让您能够以中心化 外部化和动态化的方式挂历所有环境的配置 动态配置消除了配置变更时 重新部署应用和服务的需要 配置中心化管理让
  • 如何将子窗口的值传到父窗口去调用

    这是我当初的问题 现在我想实现这样一个功能 现在父窗口有一个select控件 同时有一个 增加 按钮 点击按钮 弹出一个窗口 这时弹出窗口也有一个table 同时有一个 确认 按钮 table中有若干项 每一行对应一条记录 并有一个chec
  • 前端VUE项目部署到远程服务器

    文章目录 1 基础介绍 2 准备VUE项目 3 服务器安装 nginx服务器 4 启动nginx 5 修改nginx 配置 6 打包部署VUE项目 1 基础介绍 VUE项目 前后端分离 前后端部署到同一个服务器上 服务器 腾讯云轻量应用服务
  • 关于order by后面接条件查询

    适用场景 如表tab a 有三个字段 如果field1非空则按升序排列 如果field1是空再排field2 如果 field2非空升序排列 如果field2是空再排field3 如果field3非空则升序排列 如果field3是空 例子1
  • linux+应用程序运行日志,Linux 系统运行着许多子系统和应用程序。您可以使用系统日志记录从启动时就收集有关运行中系统的数据。有时...

    概述 在本教程中 您将学习以下内容 配置 syslog 守护程序 了解标准设施 优先级和操作 配置日志轮换 了解 rsyslog 和 syslog ng 系统内部发生了什么 Linux 系统运行着许多子系统和应用程序 您可以使用系统日志记录
  • c++ 双端队列 deque用法解析

    1 deque的作用 deque即双端队列 它的用法非常强大 可以代替栈stack 队列queue 向量容器vector等等 因为它能像栈一样后进先出 也能像queue一样先进先出 还能像vector一样随机访问 同时支持sort lowe