当前位置: 首页 > news >正文

C++方向知识汇总(三)

关于Vector

1.vector是什么?常用场景?底层用了什么数据结构?

答:

vector是动态数组,支持快速随机访问、适合频繁读取、尾部增删的场景(如有序数组遍历)

底层是基于连续分配的数组,类似于动态扩容数组,采用三个指针实现

2.vector的扩容机制是怎样的?扩容时会发生什么?

答:

默认按1.5倍扩容,vs下是2倍

扩容分三步:申请新内存、拷贝原数据到新内存、释放原内存(原迭代器失效)

3.vector的reserve和resize区别?

答:

reserver进行扩容,不改变size个数、提前预留空间

resize改变size个数,可能触发扩容,多余元素初始化0,小于原size则销毁多余元素,容量不变

4.请解释vector容器和他的特点?

答:

vector是c++标准模板库STL里的容器,就是一个动态数组、空间不够自动扩容、支持随机访问、可通过索引直接访问元素、事件复杂度O1,可以高效尾插尾删、中间和开头效率低

5.vector如何保证元素的连续存储

答:

使用动态分配的数组空间存储元素,分配空间在堆上,是连续的,元素不足扩容时,还是使用的连续空间,把旧数据拷贝到新连续空间上。保证了数据的连续存储

6. vector的push_back和emplace_back有什么区别?

答:

push_back需要传入对象,emplace_back可以直接传入对象的参数

push_back会触发拷贝构造,emplace_back直接在容器原地构造

push_back即使会触发移动构造,效率也不及emplace_back

7.vector的增删都是怎么做的?为什么是1.5倍或2倍扩容?

答:

push_back和insert插入 pop_back和erase删除

1.5倍或者2倍是为了防止频繁扩容,也为了减少内存浪费,1.5倍相比2倍内存浪费更少

8.vector扩容后,迭代器会怎样?

答:

所有迭代器失效

9.vector和数组有什么区别?

答:

数组大小固定,编译器确定大小,vector大小自动扩容

数组在栈上开辟空间,或者动态数组堆上,vector在堆上,自动管理内存

10.vector的底层数据结构是什么?

答:

vector的底层数据结构是动态数组

11.如何避免vector频繁扩容?

答:

提前预留空间使用reserve,避免频繁扩容

关于List

1.list的底层结构是什么?有什么特点?

答:

list底层是双向循环链表,每个节点包括数据和两个指针(前驱节点和后驱节点)

特点:内存空间不是连续的,不需要提前开辟固定大小空间
插入删除速度快,时间复杂度O1,但不支持随机访问,需从头遍历,时间复杂度On
删除只会当前迭代器失效,不影响其他迭代器

2.vector和list的核心区别是什么?各自适用场景?

答:

vector 动态数组 || 随机访问O1 || 中间插删效率低On || 可能频繁扩容 || 可能迭代器失效
list 双向链表| | 不支持随机访问On || 中间插删效率高O1 || 不存在频繁扩容 || 仅当前迭代器失效

vector适合需要频繁访问的,以尾插尾删为主的(如存储数据然后频繁查询)
list适合需要中间开头频繁插入删除的,无需随机访问的场景(如链表操作、队列)

3.list有哪些常用成员函数?与vector相比有什么特殊点?

答:

push_back push_front pop_back pop_front  insert erase splice sort

特殊:有头插头删 有splice方法 自带sort成员函数,因为不支持随机访问无法使用全局STL算法
,需使用自身的排序,时间复杂度Onlogn

4.list的迭代器为什么是双向迭代器,而不是随机访问迭代器?

答:

vector是连续数组,迭代器可通过+n -n 直接跳转

list是双向链表,节点地址不在一块,不连续,只能通过++ -- 来移动,每次一步,因为要双向迭代器

5.list如何避免内存碎片?与vector相比内存效率如何?

答:

list每个节点单独分配内存、释放也是单独释放、频繁插入删除可能导致小量内存碎片

vector是大块连续内存,扩容可能一次性释放旧内存、内存碎片相对较少

总体而言,list内存利用率低,每个节点还需要存储前驱后驱、但没有vector扩容时的峰值内存消耗

6.如何实现一个线程安全的list?

答:

线程安全需保证多线程对list的操作不需要资源竞争

方案:对List的所有操作加锁,确保某一时刻只有一个在访问
用读写锁,运行多个线程访问,不允许多个修改写入



关于map/set/unordered_map/unordered_set

1.map/set的底层数据结构是什么?为什么选择这种结构?

答:

底层是红黑树,一种近似平衡的二叉搜索树

选择它是因为有序性和高效率操作

红黑树通过严格的规则、使插入删除查找操作都在Ologn时间复杂度

相比AVL树,旋转更少、性能更佳

红黑树中序遍历是有序的,满足map/set的要求

2.map/set、multimap、multiset的核心区别是什么?

答:

map 存储键值对 key唯一 不允许重复

multimap key可以不唯一,可以重复,但是不支持[]了,因为key重复了,无法确定找那个

set 存储键值对,但key=value 不可以重复

multiset 可以重复,可能存储多个相同元素

简单来说:map/set 有去重的功能

3.与哈希容器的对比

答:

map 红黑树 有序 增删查Ologn 内存占用较低(仅存储数据和指针) 删除不影响其他迭代器

unordered_map 哈希表 无需 增删查O1,查找最坏On 内存占用较高(哈希表需预留空间) 扩容所有迭代器失效

哈希追求极致效率、适合不关心有序的场景(如缓存,哈希表计数等)

4.为什么unordered_map的查找效率平均O1,最坏On?

答:

unordered_map底层是哈希表,有时候会产生哈希冲突,大量的哈希冲突,导致几个数据被存在一个长链表/桶中,需遍历链表 时间复杂度就上去了

5.如何解决哈希冲突?

答:

可以优化,采用开链法,冲突时在链表后追加节点、链表超过指定长度转为红黑树

动态扩容,根据负载因子,超过阈值如0.7,自动扩容哈希表,重新哈希映射所有元素

6.map的insert和[]操作有什区别?

答:

两者都可以插入键值对,但是:

insert 当key不存在时插入,若存在不做操作,返回一个pair

[] 当key不存在时插入、新键值对、若存在直接修改对应的value

想要插入但不覆盖用insert,想要插入或者更新用[]

7.如何高效遍历map/set?迭代器有什么特点?

答:

迭代器遍历或者范围for遍历 

特点:是双向迭代器、因为支持++ --   不支持+n -n,跟list一样

删除只导致当前迭代器失效,不影响其他的

8.当自定义类型作为map的key或者set的元素时,需要做什么?

答:

需要自定义比较规则,因为需要排序,根据规则插入

在自定义类型中重载< 或者自定义一个仿函数

关于容器适配器stack、queue、priority_queue、deque

1. 容器适配器 stack、queue、priority_queue 的底层默认容器是什么?能否更换底层容器?

答:

stack 基于deque实现(也可以vector或list)

queue 基于 deque实现(也可以list)

priority_queue 基于vector实现(配合堆算法,也可以使用deque)

2. stack 和 queue 为什么默认选择 deque 作为底层容器,而不是 vector 或 list?

答:

平衡性的结果 stack和queue都需要高效的尾部头部插入删除 deque刚好满足 list缓存利用低 所以选用deque

deque分段连续内存、扩容成本比vector低

list节点不连续、缓存利用率低

http://www.xdnf.cn/news/1282717.html

相关文章:

  • 【MySQL基础篇】:MySQL索引——提升数据库查询性能的关键
  • 【华为机试】648. 单词替换
  • Jmeter使用第二节-接口测试(Mac版)
  • Nestjs框架: RBAC基于角色的权限控制模型初探
  • Flutter - 应用启动/路由管理
  • buildroot编译qt 5.9.8 arm64版本踩坑
  • 个人效能是一个系统
  • MaixPy简介
  • MySQL 函数
  • 达梦数据库慢SQL日志收集和分析
  • 【排序算法】⑥快速排序:Hoare、挖坑法、前后指针法
  • 算法训练营DAY57 第十一章:图论part07
  • 数集相等定义凸显解析几何几百年重大错误:将无穷多各异点集误为同一集
  • 深度学习和神经网络最基础的mlp,从最基础的开始讲
  • 数据大集网:精准获客新引擎,助力中小企业突破推广困局
  • MATLAB实现遗传算法求解路网路由问题
  • R语言机器学习算法实战系列(二十七)LASSO 与 Adaptive LASSO 在特征选择中的比较与应用
  • 【Leetcode】随笔
  • 深入浅出设计模式——行为型模式之观察者模式 Observer
  • Note4:Self-Attention
  • 能力评估:如何系统评估你的技能和经验
  • @ContextConfiguration
  • 嵌入式学习的第四十八天-中断+OCP原则
  • 矩阵游戏(二分图最大匹配)
  • 新人该如何将不同的HTML、CSS、Javascript等文件转化为Vue3文件架构
  • 大数据量下分页查询性能优化实践(SpringBoot+MyBatis-Plus)
  • Linux操作系统从入门到实战(十九)进程状态
  • HyperMesh许可使用监控
  • 从“目标烂尾”到“100%交付”:谷歌OKR追踪系统如何用“透明化+强问责”打造职场责任闭环
  • MD5:理解MD5 / MD5核心特性 / MD5 在前端开发中的常见用途 / 在线生成MD5 / js-md5