C++八股文之STL篇

news2024/11/13 16:13:10

 🤖个人主页:晚风相伴-CSDN博客

思维导图链接:STL

持续更新中……

💖如果觉得内容对你有帮助的话,还请给博主一键三连(点赞💜、收藏🧡、关注💚)吧

🙏如果内容有误或者有写的不好的地方的话,还望指出,谢谢!!!

让我们共同进步

目录

1、STL的基本组成部分

 2、常见容器的实现原理

3、map的实现原理 

 4、push_back和emplate_back的区别

5、hashtable的实现原理 

6、deque的实现原理 

7、list的实现原理 

8、各容器的时间复杂度 

9、迭代器

9.1迭代器的作用 

9.2迭代器和指针的区别 

9.3迭代器产生的原因 

9.4迭代器失效的问题 

10、resize和reserve的区别 

10.1capacity和size的区别 

10.2resize和reserve的区别 

11、map和unordered_map的区别 

11.1红黑树的特性 

12、map和set的区别

 13、哈希表和红黑树的比较

14、数组和链表的区别 

15、智能指针

15.0RAII 

15.1auto_ptr

15.2unique_ptr

15.3shared_ptr

15.4weak_ptr


 

1、STL的基本组成部分

广义上讲,STL分为三类:算法、容器和迭代器
详细的说,STL由6部分组成:容器、算法、迭代器、仿函数、适配器、空间配置器

  1. 容器(Container):是一种数据结构,如list、vector和deque等,以模版类的方法提供。
  2. 算法(Algorithm):是用来操作容器中的数据的模板函数。
  3. 迭代器(iterator):提供了访问容器中对象的方法。
  4. 仿函数(Function object):仿函数又被称之为函数对象,其实就是重载了操作符的struct,没有什么特别之处
  5. 适配器(Adaptor):简单的说就是一个接口类,专门用来修改现有类的接口,提供一种新的接口,或调用现有的函数来实现所需要的功能。主要包括三种适配器Container Adaptor、Iterator Adaptor、Function Adaptor。
  6. 空间配置器(Allocator):为STL提供空间配置的系统。其中主要工作包括两部分:(1)对象的创建与销毁

         (2)内存的获取与释放

 2、常见容器的实现原理

1.顺序容器
(1)vector
动态数组。元素在内存连续存放。随机存取任何元素都能在常数时间完成。在尾端增删元素具有较佳的性能。
(2)deque
双向队列。元素在内存连续存放。随机存取任何元素都能在常数时间完成。在两端增删元素具有较佳的性能。
(3)list
双向链表。元素在内存不连续存放。在任何位置增删元素都能在常数时间完成。不支持随机存取
2.关联式容器
元素是排序的;插入任何元素,都按相应的排序规则来确定其位置;在查找时具有非常好的性能;通常以平衡二叉树的方式实现。包含set、multiset、map、multimap,具体实现原理如下:
(1)set/multiset 头文件
set 即集合。set中不允许相同元素,multiset中允许存在相同元素。
(2)map/multimap 头文件
map与set的不同在于map中存放的元素有且仅有两个成员变量,一个名为first,另一个名为second, map根据first值对元素从小到大排序,并可快速地根据first来检索元素。
注意:map同multimap的不同在于是否允许相同first值的元素。 
3.容器适配器
(1)stack
栈,后进先出
(2)queue
队列,先进先出
(3)priority_queue
优先级队列。内部维持某种有序,然后确保优先级最高的元素总是位于头部。最高优先级元素总是第一个出列 

3、map的实现原理 

map是关联式容器,它的底层实现是红黑树。map的所有元素都是pair,同时拥有value(实值)和key(键值)。pair的第一个元素被视为键值,第二个元素被视为实值。所有元素都会根据元素的键值自动被排序。不允许键值重复。 

 4、push_back和emplate_back的区别

如果要将一个临时变量push到容器的末尾,push_back需要先构造临时对象,再将这个对象拷贝到容器的末尾,而emplace_back则直接在容器的末尾构造函数,这样就省去了拷贝的过程。 

5、hashtable的实现原理 

hashtable采用了函数映射的思想将记录的存储位置与记录的关键字关联起来,从而能够很快速地进行查找。这决定了哈希表特殊的数据结构,它同数组、链表以及二叉排序树等相比较有很明显的区别,它能够快速定位到想要查找的记录,而不是与表中存在的记录的关键字进行比较来进行查找。 

6、deque的实现原理 

deque内部实现的是一个双向队列。元素在内存连续存放。随机存取任何元素都在常数时间完成。所有适用于vector的操作都适用于deque。在两端增删元素具有较佳的性能。 

7、list的实现原理 

list内部实现的是一个双向链表。元素在内存不连续存放。在任何位置增删元素都能在常数时间完成。不支持随机存取。无成员函数,给定一个下标i,访问第i个元素的内容,只能从头部挨个遍历到第i个元素。 

8、各容器的时间复杂度 

1.vector:采用一维数组实现,元素在内存连续存放,不同操作的时间复杂度为:
插入:O(N)
查找:O(1)
删除:O(N)
2.deque:采用双向队列实现,元素在内存连续存放,不同操作的时间复杂度为:
插入:O(N)
查找:O(1)
删除:O(N)
3.list:采用双向链表实现,元素存放在堆中,不同操作的时间复杂度为:
插入:O(1)
查找:O(N)
删除:O(1)
4.map、set、multimap、multiset:这四种容器采用红黑树实现,红黑树是平衡二叉树的一种。不同操作的时间复杂度近似为:
插入:O(logN)
查找:O(logN)
删除:O(logN)
5.unordered_map/unordered_set/unordered_multimap/unordered_multiset这四种容器采用哈希表实现,不同操作的时间复杂度为:
插入:O(1),最坏:O(N)
查找:O(1),最坏:O(N)
删除:O(1),最坏:O(N) 

9、迭代器

9.1迭代器的作用 

  1. 用于指向顺序容器和关联容器中的元素
  2. 通过迭代器可以读取它指向的元素
  3. 通过非const迭代器还可以修改其指向的元素

9.2迭代器和指针的区别 

迭代器不是指针,是类模板,表现的像指针。他只是模拟了指针的一些功能,重载了指针的一些操作符,-->、++、--等。
迭代器返回的是对象引用而不是对象的值 

9.3迭代器产生的原因 

iterator类的访问方式就是把不同集合类的访问逻辑抽象出来,使得不用暴露集合内部的结构而达到循环遍历集合的效果。 

9.4迭代器失效的问题 

  1. 对于序列容器vector,deque来说,使用erase后,后边的每个元素的迭代器都会失效,后边每个元素都往前移动一位,erase返回下一个有效的迭代器。
  2. 对于关联容器map,set来说,使用了erase后,当前元素的迭代器失效,但是其结构是红黑树,删除当前元素,不会影响下一个元素的迭代器,所以在调用erase之前,记录下一个元素的迭代器即可。
  3. 对于list来说,它使用了不连续分配的内存,并且它的erase方法也会返回下一个有效的迭代器,因此上面两种方法都可以使用。

10、resize和reserve的区别 

10.1capacity和size的区别 

capacity:该值在容器初始化时赋值,指的是容器能够容纳的最大的元素的个数。还不能通过下标等访问,因此此时容器中还没有创建任何对象。

size:指的是此时容器中实际的元素个数。可以通过下标访问0-(size-1)范围内的对象。 

10.2resize和reserve的区别 

  1. resize既分配了空间,也创建了对象;reserve表示容器预留空间,但并不是真正的创建对象,需要通过insert或push_back等创建对象
  2. resize既修改capacity大小,也修改size大小;reserve只修改capacity大小,不修改size大小。
  3. 两者的形参个数不一样。resize带两个参数,一个表示容器大小,一个表示初始值;reserve只带一个参数,表示容器预留的大小

11、map和unordered_map的区别 

  1. map实现机理:map内部实现了一个红黑树(红黑树并不是非常严格的二叉搜索树,而AVL是严格的平衡二叉搜索树),红黑树有自动排序的功能,因此map内部所有元素都是有序的,红黑树的每一个节点都代表着map的一个元素。map中的元素是按照二叉树存储的,特点就是左子树上所有节点的键值都小于根节点的键值,右子树所有节点的键值都大于根节点的键值。使用中序遍历可将键值按照从小到大遍历出来。
  2. unordered_map实现机理:内部实现了一个哈希表,通过把关键码映射到hash表中一个位置来访问记录,查找时间复杂度可达O(1)。

11.1红黑树的特性 

红黑树保证最长路径不超过最短路径的二倍,因而近似平衡(最短路径就是全黑节点,最长路径就是一个红节点一个黑节点,当从根节点到叶子节点的路径上黑色节点相同时,最长路径刚好是最短路径的两倍)
特性:

  1. 节点是红色或黑色
  2. 根是黑色
  3. 叶子节点都是黑色,这里所说的叶子节点是空节点
  4. 红色节点的子节点都是黑色
  5. 红色节点的父节点都是黑色
  6. 从根节点到叶子节点的所有路径上不能有两个连续的红色节点
  7. 从任意节点到叶子节点的所有路径都包含相同数目的黑色节点

时间复杂度为logN

12、map和set的区别

map和set底层实现都是红黑树,map和set的区别在于map的值不作为键,键和值是分开的 

 13、哈希表和红黑树的比较

当需要快速查找、删除操作,并且不要求有序性时,哈希表是更好的选择。
当需要有序性、支持范围查找和有序遍历时,或者对空间利用率要求不高时,红黑树是更好的选择。 

14、数组和链表的区别 

 一、存储结构

数组是一种顺序存储结构,它在内存中是连续分配的一块空间

链表是一种链式存储结构,由一系列节点组成,每个节点包含数据域和指针域

二、内存分配

数组的内存分配是静态的,在创建数组时,需要预先指定数组的大小,并且一旦创建,其大小就不能再改变。

链表的大小可以动态地改变,根据需要在运行时添加或删除节点
三、插入和删除

数组的插入删除的时间复杂度为O(N)

链表的插入删除的时间复杂度为O(1)

四、查找

数组支持下标随机访问进行查找

链表只能通过遍历的方式进行查找

15、智能指针

15.0RAII 

资源获取即初始化,资源(如内存、文件句柄、锁等)在对象创建时自动获取,并且在对象销毁时自动释放。 

15.1auto_ptr

auto_ptr就是一个管理权转移问题

两个指针同时指向一块内存,就会两次释放同一块资源,自然报错

15.2unique_ptr

unique_ptr规定一个智能指针独占一块内存资源,当两个智能指针同时指向一块内存,编译报错。

实现原理

将拷贝构造和赋值函数声明为private或delete。不允许拷贝构造和赋值,但是支持移动构造函数,通过move把一个对象指针变成右值之后可以移动给另一个unique_ptr

15.3shared_ptr

shared_ptr可以实现多个智能指针指向相同对象,该对象和其相关资源会在引用为0时被销毁释放。

实现原理

内部有个引用计数,使用拷贝构造和赋值时,引用计数加1,当引用计数为0时,释放资源。

循环引用问题

  1. 循环引用会造成引用计数失效,从而导致内存泄漏问题。
  2. 使用weak_ptr来解决循环引用问题,weak_ptr不会使引用计数加1

线程安全性问题

在多线程的环境下,如果多个线程同时读一个shared_ptr对象是线程安全的,但是如果是多个线程对同一个shared_ptr对象进行读和写,则是线程不安全的,则需要加锁保护。

内存泄漏问题

当两个对象同时使用一个shared_ptr成员变量指向对方,会造成循环引用,使引用计数失效从而导致内存泄漏。

15.4weak_ptr

 使用weak_ptr不能知道对象计数是否为0,因为它的构造和析构不会引起计数的增加和减少

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

找搭子是什么意思?有没有找搭子的平台?靠谱找搭子软件推荐!

“找搭子” 指寻找在特定活动或兴趣方面有共同爱好的伙伴。比如饭搭子一起吃饭,运动搭子共同健身。它满足人们在特定场景下的社交需求,让生活更丰富有趣,是一种新型社交方式。以下是国内排名靠前的找搭子平台 1. 咕哇找搭子小程序&#xff1a…

Mac下nvm无法安装node问题

背景 最近换用mac开发,然后使用nvm(版本0.40.1)进行node安装的时候出现了一些问题 使用 nvm ls-remote发现只有 iojs 版本 原因可能是nodejs升级了某个协议导致的 解决方案 可以使用 NVM_NODEJS_ORG_MIRRORhttp://nodejs.org/dist nvm ls-re…

Cartographer源码理解

一、前言 最近一个半月,利用空余时间对Cartographer源码进行了简单的阅读,在这里做了个简单梳理,和大家分享交流。 cartographer源码量其实是有点大的,逐行逐句去解释实在是有心无力了,而且已经有大佬做了类似的事情…

分治算法归并排序

分治算法 基本概念 把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题…直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。 分治法的基本步骤 分治法在每一层递归上都有三个步骤: step1分…

单细胞CCA整合流程学习(SeuratV5/V4)

CCA(Canonical Correlation Analysis)和 Harmony 是两种常用于单细胞 RNA 测序(scRNA-seq)数据整合和批次效应校正的方法。 CCA 通过计算两个(或多个)数据集的线性组合,使这些组合之间的相关性…

1、vectorCast单元测试常用操作

一、自动创建测试工程 1、设置工作目录 进入软件主页面,点击file,选择set working directory,随便选择一个保存该项目的目录即可。 2、创建一个空工程 编译器选择vector自带的编译器,vectorCast MinGW C。 此时项目工程就创建好了 2.1、配置编译器节点 点击编译器节点…

JAVA毕业设计173—基于Java+Springboot+vue3的酒店民宿管理系统(源代码+数据库)

毕设所有选题: https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootvue3的酒店民宿管理系统(源代码数据库)173 一、系统介绍 本项目前后端分离(可以改为ssm版本),分为用户、员工、管理员三种角色 1、用户&#xff1a…

Nowcoder—链表的回文结构

题目描述 题目分析 1.回文结构是指一个序列或字符串从前往后读或从后往前读都是相同的。 2.时间复杂度为O(n),说明循环只能有一层;空间复杂度为O(1),说明不能额外的申请空间。 3.链表的结点最多不会超过900个。 思路 1 思路1:…

2024年数字中国创新赛-MISC

1 wireshark-1 可以看到在theanswerishere.php执行了sql注入,所以存在漏洞的PHP页面名称是theanswerishere.php 2 wireshark-2 从以上漏洞测试我们发现在一共有三列 3 wireshark-3 从这里我们可以看到注入的列名是th1sfI4g 4 wireshark-4 从这里回显包我们能看到…

鸿蒙next web组件和h5 交互实战来了

前言导读 鸿蒙next web组件这个专题之前一直想讲一下 苦于没有时间,周末把代码研究的差不多了,所以就趁着现在这个时间节点分享给大家。也希望能对各位读者网友工作和学习有帮助,废话不多说我们正式开始。 效果图 默认页面 上面H5 下面ArkU…

深度学习--------------序列模型

目录 序列数据统计工具(方案一)马尔可夫假设(方案二)潜变量模型总结 序列模型基于马尔可夫假设方式该部分总代码 单步预测多步预测k步预测该部分总代码 序列数据 实际中数据是有时序结构的。 统计工具 在时间t观察带 x t x_t xt…

二叉搜索树(Java实现)

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多数据结构知识 1.概念 二叉搜索树又称二叉排序树,或者它是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都…

【kafka-01】kafka安装和基本核心概念

Kafka系列整体栏目 内容链接地址【一】afka安装和基本核心概念https://zhenghuisheng.blog.csdn.net/article/details/142213307【二】kafka集群搭建https://zhenghuisheng.blog.csdn.net/article/details/142253288 kafka安装和基本核心概念 一,kafka安装和基本核心…

MoneyPrinterTurbo 安装使用流程

项目地址: https://github.com/harry0703/MoneyPrinterTurbo 开发环境:mac 1 git 下载 # 下载代码到本地 git clone https://github.com/harry0703/MoneyPrinterTurbo.git cd MoneyPrinterTurbo2 docker 配源 在 docker 安装目录执行以下命令显示隐藏…

Spring模块详解Ⅳ(Spring ORM和Spring Transaction)

目录 Spring ORM(Object-Relational Mapping)作用核心组件使用步骤事务管理代码演示优点挑战总结 Spring Transaction(Spring事务管理)事务的基本概念Spring事务管理的类型声明式事务管理事务的传播行为(Propagation&a…

【LabVIEW学习篇 - 25】:JKI状态机

文章目录 JKI状态机JKI状态机安装JKI状态机的基本了解状态机的运行原理示例 JKI状态机 JKI状态机的核心就是队列消息状态机用户事件处理器模式,JKI状态机采用指定格式的字符串来描述状态。 JKI状态机并没有采用队列而是采用指定的字符串进行存储,它封装…

【论文阅读】PERCEIVER-ACTOR: A Multi-Task Transformer for Robotic Manipulation

Abstract transformers凭借其对大型数据集的扩展能力,彻底改变了视觉和自然语言处理。但在机器人操作中,数据既有限又昂贵。通过正确的问题表述,操纵仍然可以从变形金刚中受益吗?我们使用peract来研究这个问题,peract…

图解Redis 02 | String数据类型的原理及应用场景

介绍 在 Redis 中,String 是一种重要的数据类型,是最基本的 key-value 结构,在这个结构中, value 是一个字符串。value 所能容纳的数据最大长度为512M。 需要注意的是,这里的字符串不只指文本数据,它还可…

Https AK--(ssl 安全感满满)

免责声明:本文仅做分享! 目录 https探测 openssl Openssl连接服务器获取基本信息 连接命令: 指定算法连接: 测试弱协议连接是否可以连接: 得到的内容包括: sslscan 在线查询证书 https AK type 中间人AK sslsplit 工具…

【C++题解】1997. 孤独的素数

欢迎关注本专栏《C从零基础到信奥赛入门级(CSP-J)》 问题:1997. 孤独的素数 类型:二维数组 题目描述: 在一个 n 行 m 列的矩阵王国中,生活着一些整数,其中一些是素数,一些不是素数…