C++语言相关的常见面试题目(三)
1. List底层实现原理
省流: list底层实现了一个双向循环链表。
每个元素(或节点)包含三个部分:数据域(_M_Storage)、前驱指针(_M_prev)、后继指针(_M_next)。
数据域:存储实际数据。
前驱指针:指向链表中当前节点之前的一个节点。
后继指针:指向链表中当前节点之后的一个节点
此外,存在一个特殊节点,通常称为哨兵节点(sentinel node)或者空节点。这个节点不存储用户定义的数据,其主要作用是简化边界条件处理。在双向循环链表的实现中,这个空节点同时作为头节点和尾节点的前驱和后继,使得链表形成一个闭环。
# 构造与析构
list<T>():默认构造函数,创建一个空的list。
list<T>(size_type n, const T& value):构造一个包含n个重复值value的list。
list<T>(const list<T>&):拷贝构造函数。
~list():析构函数,释放list占用的所有资源。
# 赋值操作
list<T>& operator=(const list<T>&):赋值运算符,复制另一个list的内容给当前list。
assign(iterator first, iterator last):将[first, last)区间内的元素赋值给list。
# 大小操作
size_type size() const:返回list中元素的数量。
bool empty() const:如果list为空则返回true,否则返回false。
void resize(size_type sz, T c = T()):调整list的大小到sz,若增加则用c填充新位置。
# 元素访问
reference front():返回第一个元素的引用。
const_reference front() const:返回第一个元素的常量引用。
reference back():返回最后一个元素的引用。
const_reference back() const:返回最后一个元素的常量引用。
# 插入与删除
iterator insert(iterator position, const T& val):在position指定的位置插入val。
void push_back(const T& val):在list末尾添加一个元素。
void push_front(const T& val):在list开头添加一个元素。
iterator erase(iterator position):删除position指定的元素并返回下一个元素的迭代器。
iterator erase(iterator first, iterator last):删除[first, last)区间内的所有元素。
void pop_back():删除最后一个元素。
void pop_front():删除第一个元素。
# 迭代器操作
iterator begin():返回指向list第一个元素的迭代器。
const_iterator begin() const:返回指向list第一个元素的常量迭代器。
iterator end():返回指向list末尾的下一个位置的迭代器。
const_iterator end() const:返回指向list末尾的下一个位置的常量迭代器。
# 其他操作
void swap(list<T>& x):交换两个list的内容。
void remove(const T& val):删除所有值为val的元素。
template <class Predicate> void remove_if(Predicate pred):根据谓词pred删除元素。
void reverse():反转list中的元素顺序。
void sort():按升序排序list中的元素(注意:list的sort函数是特化的,不能直接使用std::sort)。
void merge(list<T>& x):合并x到当前list中,要求list已排序。
2. deque的底层实现原理
deque底层基于分段数组实现,结合了动态数组和双向链表的特点。
deque继承自_Deque base。整体结构可以分为两部分:指针数组和迭代器。
指针数组:首位元素的地址空间、指针数组容量大小
迭代器:当前正在遍历的元素、当前连续空间的首尾地址,还有指向当前空间的指针(存储在指针数组中)
基础API:
# 构造与析构
deque<T>():默认构造函数,创建一个空的deque。
deque<T>(size_type n, const T& value):构造一个包含n个重复值value的deque。
deque<T>(const deque<T>&):拷贝构造函数。
deque<T>(initializer_list<T>):使用初始化列表构造deque。
~deque():析构函数,释放deque占用的所有资源。
# 赋值操作
deque<T>& operator=(const deque<T>&):赋值运算符,复制另一个deque的内容给当前deque。
assign(iterator first, iterator last):将[first, last)区间内的元素赋值给deque。
assign(size_type n, const T& value):将deque的元素替换为n个value。
# 大小操作
size_type size() const:返回deque中元素的数量。
bool empty() const:如果deque为空则返回true,否则返回false。
void resize(size_type sz, T c = T()):调整deque的大小到sz,若增加则用c填充新位置。
# 元素访问
reference front():返回第一个元素的引用。
const_reference front() const:返回第一个元素的常量引用。
reference back():返回最后一个元素的引用。
const_reference back() const:返回最后一个元素的常量引用。
# 注意:deque不直接支持下标运算符[]进行随机访问,但迭代器可用于遍历。
# 插入与删除
iterator insert(iterator position, const T& val):在position指定的位置插入val。
void push_back(const T& val):在deque末尾添加一个元素。
void push_front(const T& val):在deque开头添加一个元素。
iterator erase(iterator position):删除position指定的元素并返回下一个元素的迭代器。
iterator erase(iterator first, iterator last):删除[first, last)区间内的所有元素。
void pop_back():删除最后一个元素。
void pop_front():删除第一个元素。
# 迭代器操作
iterator begin():返回指向deque第一个元素的迭代器。
const_iterator begin() const:返回指向deque第一个元素的常量迭代器。
iterator end():返回指向deque末尾的下一个位置的迭代器。
const_iterator end() const:返回指向deque末尾的下一个位置的常量迭代器。
# 其他操作
void swap(deque<T>& x):交换两个deque的内容。
void clear():清空deque中的所有元素。
3. multiset的实现原理
概括:基于红黑树实现,允许键值重复的有序集合
简单介绍一下红黑树。红黑树是一种自平衡的二叉搜索树,它具有以下特性:
- 每个节点都带有颜色属性,可以是红色或黑色。
- 根节点和叶子节点(NIL 节点)都被认为是黑色的。
- 如果一个节点是红色的,则它的子节点必须是黑色的(也就是说,不能有两个相邻的红色节点)。
- 从任一节点到其每个叶子(NIL 节点)所经过的黑色结点数目相同。
STL multiset底层函数成员:
_Rb_tree:这是一个模板类,表示红黑树。红黑树是一种自平衡二叉搜索树,广泛用于实现关联容器(如 set 和 map)。key_type:这是红黑树中键的类型。它通常是用户定义的类型,用于标识红黑树中的元素。value_type:这是红黑树中值的类型。对于 set,key_type 和 value_type 是相同的;对于 map,value_type 是 std::pair<const key_type, mapped_type>。_Identity<value_type>:这是一个函数对象,用于返回值本身。在红黑树中,它用于从节点中提取键值对。key_compare:这是一个比较函数对象,用于比较键的大小。它决定了红黑树的排序规则。Key_alloc_type:这是一个分配器类型,用于管理红黑树中节点的内存分配。_Rep_type:这是一个类型别名,表示一个 _Rb_tree 类型的对象。通过 typedef,我们可以使用 _Rep_type 来引用 _Rb_tree<key_type, value_type, _Identity<value_type>, key_compare, Key_alloc_type> 类型。
主要API使用说明:
# 构造、复制、销毁
multiset();
explicit multiset(const Compare& comp); // Compare 是比较元素的函数对象类型。
template <class InputIterator> multiset(InputIterator first, InputIterator last, const Compare& comp = Compare()); // InputIterator 是输入迭代器类型,能够从first到last
# 遍历元素。
multiset(const multiset& ms);
~multiset();
# 元素访问(尽管直接访问接口较少,但迭代器可用于间接访问)
# 通过迭代器遍历,如上面提到的iterator, const_iterator, reverse_iterator, const_reverse_iterator。
# 迭代器
iterator begin(); // 返回multiset类型迭代器,指向第一个元素。
const_iterator begin() const;
iterator end(); // 返回multiset类型迭代器,指向最后一个元素之后的位置。
const_iterator end() const;
reverse_iterator rbegin(); // 反向迭代器,指向最后一个元素。
const_reverse_iterator rbegin() const;
reverse_iterator rend(); // 反向迭代器,指向第一个元素之前的位置。
const_reverse_iterator rend() const;
# 容量
bool empty() const;
size_type size() const; // size_type 是无符号整数类型,足够大以存储容器中可能的最大元素数量。
size_type max_size() const; // 返回理论上容器能容纳的最大元素数量。
# 修改
pair<iterator,bool> insert(const value_type& x); // value_type 是容器中存储的元素类型,iterator指向新插入元素或已存在的相等元素的位置,bool指示是否插入了新元素。
iterator insert(iterator position, const value_type& x); // 在迭代器position指示的位置附近插入元素,返回指向插入元素的迭代器。
template <class InputIterator> void insert(InputIterator first, InputIterator last); // 插入区间内的元素。
void erase(iterator position); // 删除迭代器position所指的元素。
size_type erase(const key_type& x); // 删除所有键值等于x的元素,返回删除的数量。
void swap(multiset& x); // 交换两个multiset的内容。
# 查找
iterator find(const key_type& x); // 返回指向键值等于x的第一个元素的迭代器,如果不存在则返回end()。
const_iterator find(const key_type& x) const;
size_type count(const key_type& x) const; // 返回键值等于x的元素数量。
iterator lower_bound(const key_type& x); // 返回第一个键值不低于x的元素的迭代器。
const_iterator lower_bound(const key_type& x) const;
iterator upper_bound(const key_type& x); // 返回第一个键值大于x的元素的迭代器。
const_iterator upper_bound(const key_type& x) const;
pair<iterator,iterator> equal_range(const key_type& x); // 返回一个迭代器对,分别指向键值等于x的元素范围的首尾。
pair<const_iterator,const_iterator> equal_range(const key_type& x) const;
# 比较
bool operator==(const multiset& x) const;
bool operator!=(const multiset& x) const;
bool operator<(const multiset& x) const;
bool operator>(const multiset& x) const;
bool operator<=(const multiset& x) const;
bool operator>=(const multiset& x) const;
4. 优先级队列的实现原理
STL内部使用最大最小堆实现优先级队列,STL中的priority_queue
默认使用的底层数据结构是vector
。这个容器适配器底层实现了一个最大堆,利用vector
来存储元素,因为vector
提供了快速的随机访问能力。
常用API:
构造函数:priority_queue<T>:默认构造函数,创建一个空的优先队列,默认使用 std::less<T> 作为比较函数。
explicit priority_queue(const Compare& comp):使用指定的比较函数 comp 创建一个空的优先队列。
成员函数:size_t size() const:返回优先队列中元素的数量。
bool empty() const:判断优先队列是否为空,若为空则返回 true,否则返回 false。
const T& top() const:获取优先级最高(即顶部)元素的引用,并不删除该元素。
void push(const T& value):将元素插入到优先队列中,并保持堆结构。
template <class... Args> void emplace(Args&&... args):通过传递参数直接构造新元素并插入到优先队列中,并保持堆结构。
void pop():删除顶部(即最高优先级)元素。
5. 迭代器的底层实现原理?有哪几种迭代器?
迭代器的定义:实现了一种访问容器内元素但是不会暴露容器内部实现的方式。
迭代器底层原理核心包括:
(1) 模拟指针操作:通过类对象模拟指针行为,重载解引用和递增/递减操作符,实现对容器元素的访问与遍历。
(2)标准化接口:提供一套统一的接口规范,确保不同容器迭代器的兼容性和互换性。
(3)与容器互动:依赖容器实现间接访问元素,不直接管理内存,需考虑容器变化导致的迭代器失效问题。
(4)类型系统与泛型编程:利用类型推导和模板技术,自动匹配容器类型,实现泛型迭代。
(5)抽象与解耦:隐藏容器内部结构,使算法独立于数据结构,提高代码复用性和灵活性。
这是一条吃饭博客,由挨踢零声赞助。学C/C++就找挨踢零声,加入挨踢零声,面试不挨踢!
相关文章:

C++语言相关的常见面试题目(三)
1. List底层实现原理 省流: list底层实现了一个双向循环链表。 每个元素(或节点)包含三个部分:数据域(_M_Storage)、前驱指针(_M_prev)、后继指针(_M_next)。 数据域:存储实际数据。 前驱指针:指向链表中…...

代码随想录-Day53
739. 每日温度 给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。 示例 1: …...

Android 如何通过代码实时设置EditTextView光标
背景:换肤框架下,QA进行深色浅色切换说输入框光标颜色没有改变,转UI结果UI说需要修改!!!!! 本来有方法可以设置,但是 设置后未生效。重新进入该页面才生效!&a…...

202488读书笔记|《365日创意文案》——无聊的 到底是这世间, 还是自己?懂得忘却的人才能前进
202488读书笔记|《365日创意文案》——无聊的 到底是这世间, 还是自己?懂得忘却的人才能前进 1月2月3月4月5月6月7月8月9月10月11月12月 《365日创意文案》WRITES PUBLISHING,一些日常,是烟火,也是幸福的印记。 当下也…...

iperf3: error - unable to connect to server: No route to host
1.确认iperf3版本是否统一。 2.确认防火墙是否关闭。 关闭防火墙 : systemctl stop firewalld 查看防火墙状态: systemctl status firewalld 3.重新建起链接...
正则表达式中的贪心匹配
在正则表达式中,?既可以表示数量,0次或1次,等效于 {0,1},也可以跟在其它数量限定符之后,表示非贪心匹配,即匹配时匹配搜索到的尽可能短的字符串。 下面来看一个例子: T…...
线程相关概念及操作
【1】线程的概念 1.线程-->进程会得到一个内存地址,进程是资源分配的基本单位线程才是真正进程里处理数据与逻辑的东西进程---》被分配一定的资源线程---》利用进程资源处理数据与逻辑 【2】进程和线程关系: 进程与进程之间是竞争关系,竞…...

2024最新版若依-RuoYi-Vue3-PostgreSQL前后端分离项目部署手册教程
项目简介: RuoYi-Vue3-PostgreSQL 是一个基于 RuoYi-Vue3 框架并集成 PostgreSQL 数据库的项目。该项目提供了一套高效的前后端分离的开发解决方案,适用于中小型企业快速构建现代化的企业级应用。此项目结合了 RuoYi-Vue-Postgresql 和 RuoYi-Vue3 的优点࿰…...

PHP源码:新闻门户系统(附管理后台+前台)
一. 前言 今天小编给大家带来了一款可学习,可商用的,新闻门户系统 源码,支持二开,无加密。项目可以扩展为个人博客,和一些社交论坛网址。主要功能:支持文章管理,评论管理,分类管理等…...

15kg级弹簧刀高速巡飞无人机技术详解
弹簧刀高速巡飞无人机,作为一种先进的战术导弹系统,融合了无人机与导弹的双重特性,成为了现代战争中不可或缺的侦察与打击利器。该无人机以其小巧的外形设计、优异的性能表现和广泛的适用领域,受到了全球军事领域的广泛关注。弹簧…...

中国东方资产管理25届秋招北森测评笔试如何高分通过?真题考点分析看完这篇就够了
一、东方资管校招测评题型分析 中国东方资产管理股份有限公司(中国东方资管)的校园招聘测评题型主要包括以下几个部分: 1. **计分题,行测知识**:这部分题量大约在56-57题左右,分为不同的模块进行计时测试。…...
简写单词BC149
BC149 简写单词 题目描述输入描述:输出描述: 题目描述 规定一种对于复合词的简写方式为只保留每个组成单词的首字母,并将首字母大写后再连接在一起 比如 “College English Test”可以简写成“CET”,“Computer Science”可以简写…...

Chapter11让画面动起来——Shader入门精要学习笔记
Chapter11让画面动起来 一、Unity Shader中的内置变量(时间篇)二、纹理动画1.序列帧动画2.滚动背景 三、顶点动画1.流动的河流2.广告牌3.注意事项①批处理问题②阴影投射问题 一、Unity Shader中的内置变量(时间篇) Unity Shader…...

c++之命名空间详解(namespace)
引例 在学习之前我们首先了来看这样一个情形: 在c语言下,我们写了两个头文件:链表和顺序表的。我们会定义一个type(typedef int type)方便改变数据类型(比如将int改成char),来做到整体代换。 但是我们两个头文件里面…...
【大模型】在大语言模型的璀璨星河中寻找道德的北极星
在大语言模型的璀璨星河中寻找道德的北极星 引言一、概念界定二、隐私保护的挑战2.1 数据来源的道德考量2.2 敏感信息的泄露风险 三、偏见与歧视的隐忧3.1 训练数据的偏见传递3.2 内容生成的不公倾向 四、责任归属的模糊地带4.1 生成内容的责任界定4.2 自动化决策的伦理考量 五…...

嵌入式Linux之Uboot简介和移植
uboot简介 uboot 的全称是 Universal Boot Loader,uboot 是一个遵循 GPL 协议的开源软件,uboot是一个裸机代码,可以看作是一个裸机综合例程。现在的 uboot 已经支持液晶屏、网络、USB 等高级功能。 也就是说,可以在没有系统的情况…...
算法整理——【贪心算法练习(1)】
上一篇博客算法整理——【贪心算法简述】-CSDN博客,我们介绍了贪心算法的基础知识,现在我们要对此进行进一步练习。 一、跳跃游戏II 例题为45. 跳跃游戏 II - 力扣(LeetCode),给定一个长度为 n 的 0 索引整数数组 nu…...

人脸识别课堂签到系统【PyQt5实现】
人脸识别签到系统 1、运用场景 课堂签到,上班打卡,进出门身份验证。 2、功能类别 人脸录入,打卡签到,声音提醒,打卡信息导出,打包成exe可执行文件 3、技术栈 python3.8,sqlite3,opencv,face_recognition,PyQt5,csv 4、流程图 1、导入库 2、编写UI界面 3、打…...

Linux dig命令常见用法
Linux dig命令常见用法 一、dig安装二、dig用法 DIG命令(Domain Information Groper命令)是常用的域名查询工具,通过此命令,你可以实现域名查询和域名问题的定位,对于网络管理员和在域名系统(DNS)领域工作的小伙伴来说,它是一个非…...

数学建模论文写作文档word
目录 1. 摘要写法1.1 确定题目与方法1.2 编写开头段落1.3 填写问题一1.4 重复步骤3填写其他问题1.5 编写结尾段落1.6 编写关键词 2. 问题重述2.1 问题背景2.2 问题提出 3. 问题分析4. 问题X模型的建立与求解5. 模型的分析5.1 灵敏度分析5.2 误差分析(主要用于预测类…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...