C++学习笔记(二十六)——deque

ops/2025/3/25 23:52:37/

一、std::deque

(1)deque与其适用场景

std::deque(双端队列,double-ended queue)是 C++ STL(标准模板库)中的序列容器,类似于 std::vector,但支持在两端高效地插入和删除元素

适用场景:

  • 需要高效的头部和尾部插入/删除(比 vector 头部插入快)。
  • 仍然需要 O(1) 随机访问(比 list 访问速度快)。
  • 适用于队列和缓存管理(如 std::queue 底层实现)。

包含头文件

#include <deque>

(2)std::deque vs std::vector

特性std::dequestd::vector
随机访问O(1)O(1)
动态扩展前后两端扩展只能尾部扩展
插入/删除两端插入/删除 O(1)头部/中间插入 O(n)
内存管理多块内存块连续内存

std::deque 适用于:

  • 频繁在头部和尾部插入/删除元素
  • 仍然需要支持随机访问

std::vector 适用于:

  • 只在尾部插入/删除
  • 需要连续存储,提高访问性能

二、std::deque 的创建

函数作用
deque<T> dq;默认构造一个空deque
deque<T> dq(n, val);创建一个大小为n,值为valdeque
deque<T> dq = {val1, val2, ...}; 使用列表初始化
deque<T> dq2(dq1);拷贝构造
deque<T> dq2(dq1.begin(), dq1.end());迭代器范围构造

(1) 定义 deque

示例:

#include <iostream>
using namespace std;
#include <deque>void printDeque(deque<int> d)
{for (auto it = d.begin(); it != d.end(); ++it){cout << *it << " ";}cout << endl;
}int main() {deque<int> d1;             // 空双端队列deque<int> d2(5, 100);     // 5 个 100deque<int> d3 = {1, 2, 3}; // 直接初始化deque<int> d4(d3);         // 复制 d3printDeque(d1);printDeque(d2);printDeque(d3);printDeque(d4);system("pause");return 0;
}

(2) 向 deque 添加元素

示例:

#include <iostream>
using namespace std;
#include <deque>void printDeque(deque<int> d)
{for (auto it = d.begin(); it != d.end(); ++it){cout << *it << " ";}cout << endl;
}int main() {deque<int> dq;dq.push_back(10);   // 在尾部添加 10dq.push_back(20);dq.push_back(30);dq.push_front(40);  // 在头部添加 40printDeque(dq);system("pause");return 0;
}

注意:

  • push_back:在容器尾部添加元素。
  • push_front:在容器头部添加元素。

(3) 访问元素

函数作用
operator[]随机访问(deque[i]
at(index)访问指定索引(带边界检查)
front()返回首元素
back()返回尾元素

示例:

#include <iostream>
using namespace std;
#include <deque>int main() {deque<int> dq;dq.push_back(10);   // 在尾部添加 10dq.push_back(20);dq.push_back(30);dq.push_back(40); cout << dq[0] << endl;        // 直接访问(不安全)cout << dq.at(1) << endl;     // 安全访问(越界会抛异常)cout << dq.front() << endl;   // 获取第一个元素cout << dq.back() << endl;    // 获取最后一个元素system("pause");return 0;
}

三、遍历 deque

(1) 使用 for 循环

示例:

#include <iostream>
using namespace std;
#include <deque>int main() {deque<int> dq = {10, 20, 30, 40};for (int i = 0; i < dq.size(); i++){cout << dq[i] << " ";}cout << endl;system("pause");return 0;
}

(2) 使用范围 for

示例:

#include <iostream>
using namespace std;
#include <deque>int main() {deque<int> dq = {10, 20, 30, 40};for (int x : dq){cout << x << " ";}cout << endl;system("pause");return 0;
}

注意:

  • 使用范围基 for 循环(range-based for loop),可以简洁、直观地遍历deque容器。

(3) 使用迭代器

函数返回类型作用
begin()iterator / const_iterator指向元素
end()iterator / const_iterator指向尾后位置
rbegin()reverse_iterator / const_reverse_iterator指向元素(反向遍历)
rend()reverse_iterator / const_reverse_iterator指向首元素前的位置(反向遍历)
cbegin()const_iterator返回只读迭代器,指向元素
cend()const_iterator返回只读迭代器,指向尾后
crbegin()const_reverse_iterator返回只读反向迭代器,指向元素
crend()const_reverse_iterator返回只读反向迭代器,指向首元素前

示例:

#include <iostream>
using namespace std;
#include <deque>int main() {deque<int> dq = {10, 20, 30, 40};for (auto it = dq.begin(); it != dq.end(); ++it){cout << *it << " ";}cout << endl;system("pause");return 0;
}

四、std::deque 的常用操作

(1) 插入和删除

函数作用
push_back(value)尾部插入元素
push_front(value)头部插入元素
pop_back()删除尾部元素
pop_front()删除头部元素
insert(pos, value)在指定位置插入
erase(pos)删除指定位置的元素

示例:

#include <iostream>
using namespace std;
#include <deque>void printDeque(deque<int> d)
{for (auto it = d.begin(); it != d.end(); ++it){cout << *it << " ";}cout << endl;
}int main() {deque<int> dq = {1, 2, 3, 4};// 在指定位置插入dq.insert(dq.begin() + 2, 100); // 在索引 2 位置插入 100, {1,2,100,3,4}printDeque(dq);// 删除元素dq.erase(dq.begin());           // 删除第一个元素,{2,100,3,4}printDeque(dq);dq.erase(dq.begin() + 2);       // 删除索引 2 处的元素,{2,100,4}printDeque(dq);// 清空 dequedq.clear();printDeque(dq);system("pause");return 0;
}

(2) deque 的大小

函数作用
size()返回元素个数
empty()判断是否为空
resize(n, value)调整大小,超过填充value
shrink_to_fit()减少内存占用

示例:

#include <iostream>
using namespace std;
#include <deque>void printDeque(deque<int> d)
{for (auto it = d.begin(); it != d.end(); ++it){cout << *it << " ";}cout << endl;
}int main() {deque<int> dq = {1, 2, 3, 4};cout << dq.size() << endl;     // 获取元素个数cout << dq.empty() << endl;    // 是否为空dq.resize(10);printDeque(dq);dq = {1, 2, 3, 4};dq.resize(10, 1000);printDeque(dq);system("pause");return 0;
}

(3) 交换 deque

示例:

#include <iostream>
using namespace std;
#include <deque>void printDeque(deque<int> d)
{for (auto it = d.begin(); it != d.end(); ++it){cout << *it << " ";}cout << endl;
}int main() {deque<int> a = {1, 2, 3};deque<int> b = {4, 5, 6};cout << "交换前:" << endl;printDeque(a);printDeque(b);a.swap(b);  // 交换 a 和 b 的内容cout << "交换后:" << endl;printDeque(a);printDeque(b);system("pause");return 0;
}

注意:
a.swap(b); 交换 a 和 b 的所有元素,避免数据拷贝,提高性能。

(4) deque 排序

函数作用
sort(dq.begin(), dq.end())排序
reverse(dq.begin(), dq.end())逆序
find(dq.begin(), dq.end(), val)查找元素
binary_search(dq.begin(), dq.end(), val)二分查找(需排序)

示例:

#include <iostream>
using namespace std;
#include <deque>
#include <algorithm>void printDeque(deque<int> d)
{for (auto it = d.begin(); it != d.end(); ++it){cout << *it << " ";}cout << endl;
}int main() {deque<int> dq = {3, 1, 4, 5, 2};printDeque(dq);sort(dq.begin(), dq.end());  // 升序排序printDeque(dq);reverse(dq.begin(), dq.end());  // 逆序printDeque(dq);system("pause");return 0;
}

http://www.ppmy.cn/ops/169785.html

相关文章

HDFS相关的面试题

以下是150道HDFS相关的面试题&#xff0c;涵盖了HDFS的基本概念、架构、操作、数据存储、高可用性、权限管理、性能优化、容错机制、与MapReduce的结合、安全性、数据压缩、监控与管理、与YARN的关系、数据一致性、数据备份与恢复等方面&#xff0c;希望对你有所帮助。 HDFS基本…

C语言简介

C语言是一种通用的、过程式的编程语言&#xff0c;由Dennis Ritchie在20世纪70年代初于贝尔实验室开发。它最初是为UNIX操作系统设计的&#xff0c;但后来因其高效、灵活和可移植性强的特点&#xff0c;成为了一种广泛使用的编程语言。C语言对许多现代编程语言&#xff08;如C、…

【Hbase】查看所有表

在 HBase 中&#xff0c;查看所有表时&#xff0c;通常不需要指定命名空间&#xff0c;除非有特殊需求或配置。以下是一些具体情况&#xff1a; 默认情况下 • HBase Shell&#xff1a;使用list命令时&#xff0c;默认会列出所有命名空间中的所有表&#xff0c;而不仅仅是默认…

struts1+struts2项目兼容升级到了spring boot 2.7

原项目比较复杂&#xff0c;集成了各种框架&#xff08;struts1 struts2 spring3等&#xff09;&#xff0c;趁工作之余练练手&#xff0c;学习一下springboot。大概花了一周时间才调通。 一、调整jar版本&#xff0c;寻找合适的版本。 第一步、首先原项目JDK6&#xff0c;要…

学习记录-Ajax-自封装axios函数

目录 自封装axios函数封装axios函数实现步骤1. 准备阶段2. 实现无参get请求3.实现有参get请求4. 实现post请求 完整实例代码 自封装axios函数 封装axios函数实现步骤 1. 准备阶段 理解axios函数的底层原理&#xff0c;包括Promise,XMLHttpRequest等概念 XMLHttpRequest工作…

C#中迭代器和IEnumerator 接口和IEnumerable 接口的区别和作用

在C#里&#xff0c;迭代器、IEnumerator 接口以及 IEnumerable 接口都和集合遍历相关&#xff0c;不过它们的作用和使用场景存在差异。下面为你详细介绍&#xff1a; 1. IEnumerable 接口 作用&#xff1a;IEnumerable 接口用于表明一个类或结构可以被迭代。实现了 IEnumerab…

Milvus vs. ElasticSearch:向量库检索性能测试

目录 1. 构建检索库2. 测试条件3. 测试结果4. 性能分析5. 结论 1. 构建检索库 构建通用场景库总计约2万张。构建车辆数据库总计约12万张。构建公共数据库&#xff0c;包括Flickr30k、COCO、nlvr2、vqa等数据集约43万张。 2. 测试条件 环境说明&#xff1a;分别单机部署Milvu…

java+selenium(资源全备,打开已使用浏览器信息,保留用户信息)

javaselenium(资源全备&#xff0c;打开已使用浏览器信息&#xff0c;保留用户信息) 一、介绍 我的代码可以实现以下效果&#xff1a; 保留用户信息&#xff0c;好处&#xff1a;可以在登录好一个账号后还保留原来的token验证信息 使用javaselenium实现爬取vue元素内容&…