C++初学者指南-5.标准库(第一部分)--顺序容器

C++初学者指南-5.标准库(第一部分)–顺序容器

文章目录

  • C++初学者指南-5.标准库(第一部分)--顺序容器
    • 标准顺序容器
    • 常见特点
      • 规律性:复制,分配,比较
      • 类型推导(C++17)
      • 常用接口部分
    • array<T,size>
    • vector\<T>
      • C++ 的默认容器
      • 快速回顾
      • 迭代器范围
      • 插入元素
      • 插入和原地构造(C++11)
      • 删除元素
      • 释放内存 / 释放空间
      • 注意!插入/删除之后!
      • Vector接口概览
    • deque\<T>
      • deque接口概览
    • list\<T>
      • list接口概览
    • forward_list\<T>
      • forward_list接口概览
    • 指导方针
    • 相关链接

标准顺序容器

在这里插入图片描述

array<T,size>固定尺寸连续数组
vector<T>动态连续数组;O(1)时间复杂度的增长策略;C++的“默认”容器。
deque<T>双向队列,可以快速的在两端插入和删除。
list<T>双向链表;O(1)时间复杂度的插入、删除和剪接;实际上通常比vector要慢。
forward_list单向链表;O(1)时间复杂度的插入、删除和剪接;比list需要更少的内存;实际上比vector要慢。

常见特点

规律性:复制,分配,比较

所有标准序列容器都是规则类型:

  • 深度复制:复制将创建一个新的容器对象并复制所有包含的值
  • 深度赋值:从源到目标的所有包含对象都会被复制
  • 深度比较:比较两个容器比较包含的对象
  • 深层所有权:销毁容器将销毁所有包含的对象

在这里插入图片描述

std::vector<int> a {4,7,1,9};
std::vector<int> b {1,2,3};
bool equal1 = (a == b);  // false
b = a;  // 复制赋值 ⇒ b: 4 7 1 9
bool equal2 = (a == b);  // true
a[0] = 3;     // a: 3 7 1 9     b: 4 7 1 9
bool equal3 = (a == b);  // false
// 制作精确复制品的不同方式,
// 用拷贝构造新容器
std::vector<int> a2 {a};
std::vector<int> a3 (a);
std::vector<int> a4 = a;
auto a5 {a};
auto a6 (a);
auto a7 = a;

类型推导(C++17)

从C++17开始,可以从构造函数调用中推断元素类型。

std::vector v {1, 2, 3, 4};std::vector<int>
std::vector v {1.f, 2.3f, 4.5f};std::vector<float>
std::vector v {1., 2.3, 4.6};std::vector<double>
struct p2 { int x; int y; };
std::vector v {p2{1,2}};std::vector<p2>

常用接口部分

正向遍历的迭代器

可以通过标准序列容器的成员函数从中获取:
container.begin() → @first_element
container.end() → @one_behind_last_element

或者使用独立函数: (C++11)
std::begin(container) → @first_element
std::end(container) → @one_behind_last_element

如果你不熟悉迭代器是什么,请参考这篇文章。

前向遍历的常量迭代器

可以通过标准序列容器的成员函数从中获取:
container.cbegin() → @first_element
container.cend() → @one_behind_last_element

或者使用独立函数: (C++11)
std::cbegin(container) → @first_element
std::cend(container) → @one_behind_last_element

空查询
要么用成员函数:
container.empty() → true, 如果容器没有元素
或者用独立函数:
std::empty(container) → true, 如果容器没有元素

类型接口

  • container::value_type
  • container::size_type
  • container::iterator
  • container::const_iterator
    ,
using con_t = std::vector<double>;
con_t::size_type i = 0;         // std::size_t
auto x = con_t::value_type{0};  // double

array<T,size>

  • 无开销随机存取
  • 快速遍历;适用于线性搜索
  • size 必须是常量表达式(= 编译时已知)
  • 不支持大小更改操作(调整大小、插入、擦除等)
  • 如果元素类型具有较高的复制/赋值开销(重新排序元素需要复制/移动它们),则可能会变慢

在这里插入图片描述
运行示例代码

vector<T>

C++ 的默认容器

在这里插入图片描述

  • 无开销随机存取
  • 快速遍历;适用于线性搜索
  • 以平摊常数时间插入
  • 如果在开头或随机位置频繁进行插入/删除操作,可能会变得很慢
  • 如果元素类型具有较高的复制/赋值开销(重新排序元素需要复制/移动它们),则可能会变慢
  • 所有可以改变容量的操作(插入,尾部添加,等等)可能会使任何向量元素的引用/指针失效
  • 对于非常大量的值,分配时间可能很长(可以缓解,看这里)

快速回顾

在这里插入图片描述
运行示例代码
在这里插入图片描述

迭代器范围

在这里插入图片描述
注意:迭代器范围的末尾迭代器 q 指向最后一个元素的后面的位置。

插入元素

【】在这里插入图片描述
迭代器范围

插入和原地构造(C++11)

在这里插入图片描述

删除元素

在这里插入图片描述
删除不会影响容量,也就是说,向量vector的任何内存都不会被释放。

释放内存 / 释放空间

从向量中删除元素永远不会改变容量,因此也永远不会释放任何内存。

.shrink_to_fit() (可能有效)

  • ISO标准并不要求它实际收缩
  • 标准库的实现可能决定不进行收缩
vector<int> v;
// add a lot of elements …
// erase elements …
v.shrink_to_fit(); C++11

保证有效:

  • 制作临时副本 ⇒ 副本恰好与元素相匹配
  • 通过交换/移动交换内存缓冲区
  • 临时的东西会自动销毁
vector<int> v;
// add a lot of elements …
// erase elements …
// shrink: make a new copy and
// replace v's content with it:
v = vector<int>(v);       C++11-20
// or:
v.swap( vector<int>(v) ); C++98-20

注意!插入/删除之后!

如果一个向量的容量被改变或元素被insert、push_back、emplace、emplace_back、erase、=、assign、resize、reserve等操作移动时,所有迭代器都会无效化。(交换两个向量的内容并不会使迭代器无效,除了末尾的迭代器。)
在这里插入图片描述
迭代器失效操作概览

操作无效的迭代器
只读操作
swap, std::swap仅在结束位置end()
reserve, shrink_to_fit如果容量改变了:全部无效。 否则:无
push_back, emplace_back如果容量变了:全部无效。 否则:只有end()
insert, emplace如果容量改变:全部无效 否则:仅在插入点或之后(包括末尾end())
resize如果容量改变:全部无效:只有 end() 和用于擦除的元素的迭代器
pop_back迭代器指向被删除元素和末尾位置
erase用于擦除元素及其后面所有元素的迭代器(包括. end())
clear, operator=, assign全部无效

Vector接口概览

在这里插入图片描述

deque<T>

双端队列 在这里插入图片描述

  • 常数时间的随机访问(极小的开销)
  • 快速遍历;适合线性搜索
  • 两端具有良好的插入和删除性能
  • 插入操作不会使元素的引用或指针失效
  • 如果随机位置的插入/删除操作占主导地位,可能会变得比较慢
  • 如果元素类型具有较高的复制/赋值开销(重新排序元素需要复制/移动它们),则可能会变慢
  • 大量值的分配可能需要很长时间(可以通过一些方法来缓解,参见这里)

在这里插入图片描述

deque接口概览

在这里插入图片描述

list<T>

双向链表
在这里插入图片描述

  • 重组操作不需要移动/复制元素(适合存储拷贝/赋值成本高的大对象)
  • 常量时间拼接(完整列表)
  • 只能在线性时间内进行随机访问
  • 由于内存局部性差,遍历速度慢
    在这里插入图片描述

list接口概览

在这里插入图片描述

forward_list<T>

前向链表
在这里插入图片描述

  • 比list占用更少的内存

  • 重组操作不需要移动/复制元素(适合存储拷贝/赋值成本高的大对象)

  • 常量时间拼接(完整列表)

  • 随机访问只能在线性时间内完成

  • 由于内存局部性不好,导致遍历速度慢

  • 只能向前遍历

  • 由于仅支持前向链接,接口有点复杂

    • 不能: size(), back(), push_back(), pop_back(), insert()
    • 替代: insert_after(), splice_after(), before_begin()

    在这里插入图片描述

forward_list接口概览

在这里插入图片描述

指导方针

我应该使用哪种顺序容器?
默认选择:std::vector !

在这里插入图片描述

相关链接

std::vector
cppreference: 容器库
一个C++容器和算法教程
5分钟5个数据结构

顺序容器概览表
在这里插入图片描述
附上原文链接

如果文章对您有用,请随手点个赞,谢谢!^_^

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/790211.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决多个栅格行列数不一致,无法对齐方法

最近在处理栅格数据&#xff0c;要求做空间关联分析。检查数据后发现多个栅格数据像元大小以及行列数不一致&#xff0c;导致出现这种原因是由于数据来源不一致以及数据精度不同导致的&#xff0c;在做空间关联分析前&#xff0c;需要对数据预处理。 一、准备工作 &#xff08…

【ArcGIS 小技巧】为国空用地字段设置属性域,快速填充属性值并减少出错

属性域属性是描述字段类型可用值的规则。可用于约束表或要素类的任意特定属性中的允许值。——ArcGIS Pro 帮助文档 简单理解属性域&#xff1a;对于一个含义为性别的字段&#xff0c;我们一般会给的属性值有男、女两种。我们可以将这两种属性值制作成属性域并指定给该字段&…

Mysql如何高效ALTER TABL

ALTER TABLE 缺点 MySQL 的ALTER TABLE 操作的性能对大表来说是个大问题。 MySQL MySQL 执行大部分修改表结构操作的方法是用新结构的 创建一个&#xff0c;空表从旧表中查出所有数据插入&#xff0c;新表然后删除旧。表这样操作可能需要花费很长&#xff0c;时间 如内果存不…

剪画小程序:父辈的照片模糊不清晰,怎么变清晰!

在我们的记忆深处&#xff0c;父辈和爷爷辈的影像总是伴随着一些模糊不清晰的老照片。这些照片或许没有现代摄影技术的高清与细腻&#xff0c;但它们却承载着无比厚重的岁月痕迹和情感温度。 每一张模糊的老照片&#xff0c;都是时光的切片。它们可能是父辈年轻时的纯真笑容&am…

redis批量删除keys,用lua脚本。

文章目录 现象解决方法 现象 系统报错&#xff1a; misconf redis is configured to save ....后查看机器内存。 是内存满了&#xff0c;需要删除其中的key 解决方法 (1) 编写一个脚本&#xff0c;放在redis-cli.exe同一个目录 (2) 脚本内容如下&#xff1a; -- 使用Lua脚…

信息学奥赛初赛天天练-43-CSP-J2020基础题-链表、连通图、2进制转10进制、栈、队列、完全二叉树、哈希表应用

PDF文档公众号回复关键字:20240710 2020 CSP-J 选择题 单项选择题&#xff08;共15题&#xff0c;每题2分&#xff0c;共计30分&#xff1a;每题有且仅有一个正确选项&#xff09; 7.链表不具有的特点是&#xff08;&#xff09; A.可随机访问任一元素 B.不必事先估计存储…

关于前端数据库可视化库的选择,vue3+antd+g2plot录课计划

之前&#xff1a;antdv 现在&#xff1a;g2plot https://g2plot.antv.antgroup.com/manual/introduction 录课内容&#xff1a;快速入门 图表示例&#xff1a; 选择使用比较广泛的示例类型&#xff0c;录课顺序如下&#xff1a; 1、折线图2、面积图3、柱形图4、条形图5、饼…

SpringCloud代码实战

项目结构 实例实现功能:实现通过id查询用户的订单信息 OrderCommon&#xff1a;公共的一些模块类型&#xff0c;此处为一个user对象 Eureka-Service:配置Eureka的启动类&#xff0c;服务端 Order-Service:提供查询功能的服务端 Order-Client:查询的客户端 OrderCommon代码…

西安明德理工学院师生莅临泰迪智能科技开展参观见习活动

为进一步深化校企合作&#xff0c;落实高校应用型人才培养。7月8日&#xff0c;西安明德理工学院与广东泰迪智能科技股份有限公司联合开展学生企业见习活动。西安明德理工学院金融产业学院副院长刘敏、金融学专业负责人张莉萍、金融学专业教师曹艳飞、赵浚妤、泰迪智能科技董事…

软件架构之架构风格

软件架构之架构风格 9.3 软件架构风格9.3.1 软件架构风格分类9.3.2 数据流风格9.3.3 调用/返回风格9.3.4 独立构件风格9.3.5 虚拟机风格9.3.6 仓库风格 9.4 层次系统架构风格9.4.1 二层及三层 C/S 架构风格9.4.2 B/S 架构风格9.4.3 MVC 架构风格9.4.4 MVP 架构风格 9.5 面向服务…

【日常记录】【插件】js 获取浏览器信息、操作系统等相关信息

文章目录 1. 原生方式2. 插件的方式2.1 Bowser 的基本使用2.2 UAParser2.3 Platform.js 参考链接 1. 原生方式 原生方式可以通过 navigator.userAgent 来获取 需要写一个正则来匹配&#xff0c;获取相关的信息 2. 插件的方式 获取浏览器版本相关信息的库主要有以下几个 Bowser&…

01MFC建立单个文件类型——画线

文章目录 选择模式初始化文件作用解析各初始化文件解析类导向创建鼠标按键按下抬起操作函数添加一个变量记录起始位置注意事项代码实现效果图虚实/颜色线选择模式 初始化文件作用解析 运行: 各初始化文件解析 MFC(Microsoft Foundation Classes)是一个C++类库,用于在Win…

力扣 双指针基础

class Solution {public void moveZeroes(int[] nums) {int l 0;//慢指针但先走for (int r 0; r < nums.length; r) {//快指针&#xff0c;遍历次数if (nums[r] 0) continue;//l比r先到&#xff0c;在此处定住l&#xff0c;r继续移动int t nums[l];nums[l] nums[r];num…

今天小编强烈推荐几款国产APP!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 今天小编强烈推荐几款国产APP,算得上是国产之光。如果能帮助到大家&#xff0c;别忘了给小编点点赞加关注哟&#xff01;更多精彩还在后面。 一、…

节点流与处理流:深入解析Java中的IO流

节点流与处理流&#xff1a;深入解析Java中的IO流 1、节点流&#xff08;Node Stream&#xff09;1.1 定义1.2 好处1.3 示例 2、处理流&#xff08;Processing Stream&#xff09;2.1 定义2.2 好处2.3 创建特征2.4 示例 3、总结 &#x1f496;The Begin&#x1f496;点点关注&…

关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论

目录 问题一&#xff1a;关于string的\0问题讨论 问题二&#xff1a;C标准库中的string内存是分配在堆上面吗&#xff1f; 问题三&#xff1a;string与vector的capacity大小设计的特点 问题四&#xff1a;string的流提取问题 问题五&#xff1a;迭代器失效 问题六&#xf…

05_Shell索引数组

05_Shell索引数组 数组定义 #!/bin/basharr(1 2 3 "www.baidu.com")获取数组元素 #!/bin/basharr(1 2 3 "www.baidu.com")#通过下表获取元素 下标从1开始 ${arr[1]}#获取数组所有元素 ${arr[*]} 或者 ${arr[]}#获取数组长度 ${#arr[*]} 或者 ${#arr[*]}#获…

LeetCode(2)合并链表、环形链表的约瑟夫问题、链表分割

一、合并链表 . - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ typedef struct ListNode ListNode; struct ListNode* mergeTwoLists(struct …

选择最佳工具:评估8款顶级App界面设计软件

在如今的数字化时代&#xff0c;设计师也离不开各种界面设计软件来辅助自己的设计工作。在各种界面设计软件的帮助下&#xff0c;设计师们能够更好、更快地完成自己的设计工作。而今天本文要为大家推荐的这 8 款界面设计软件&#xff0c;分别是国产APP界面设计软件、Figma、Ske…

【数据库】Redis主从复制、哨兵模式、集群

目录 一、Redis的主从复制 1.1 主从复制的架构 1.2 主从复制的作用 1.3 注意事项 1.4 主从复制用到的命令 1.5 主从复制流程 1.6 主从复制实现 1.7 结束主从复制 1.8 主从复制优化配置 二、哨兵模式 2.1 哨兵模式原理 2.2 哨兵的三个定时任务 2.3 哨兵的结构 2.4 哨…