C++语言相关的常见面试题目(三)

news2025/1/9 1:40:37

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的实现原理 

概括:基于红黑树实现,允许键值重复的有序集合

简单介绍一下红黑树。红黑树是一种自平衡的二叉搜索树,它具有以下特性:

  1. 每个节点都带有颜色属性,可以是红色或黑色。
  2. 根节点和叶子节点(NIL 节点)都被认为是黑色的。
  3. 如果一个节点是红色的,则它的子节点必须是黑色的(也就是说,不能有两个相邻的红色节点)。
  4. 从任一节点到其每个叶子(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++就找挨踢零声,加入挨踢零声,面试不挨踢!

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

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

相关文章

一篇就够了,为你答疑解惑:锂电池一阶模型-在线参数辨识(附代码)

锂电池一阶模型-在线参数辨识 背景在线 VS 离线 参数辨识递推最小二乘法一阶戴维南Z域离散表达式 背景 锂电池一阶戴维南等效模型的基础知识和离线辨识方法&#xff0c;已经在上一期非常详细地讲解了一轮&#xff08;上期文章请戳此处&#xff09;&#xff0c;本期继续讲解一下…

美光科技在2024年1γ工艺技术在10纳米级别启动EUV试产

美光科技&#xff08;Micron&#xff09;在2024年针对其1γ&#xff08;1-gamma&#xff09;工艺技术在10纳米级别启动EUV&#xff08;极紫外光刻&#xff09;试产&#xff0c;这标志着存储行业巨头在EUV采用上的重要一步&#xff0c;尽管相比英特尔和台积电等其他半导体制造商…

PIP换源的全面指南

##概述 在Python的世界里&#xff0c;pip是不可或缺的包管理工具&#xff0c;它帮助开发者安装和管理Python软件包。然而&#xff0c;由于网络条件或服务器位置等因素&#xff0c;直接使用默认的pip源有时会遇到下载速度慢或者连接不稳定的问题。这时&#xff0c;更换pip源到一…

SpringBoot整合DataX数据同步(自动生成job文件)

SpringBoot整合Datax数据同步 文章目录 SpringBoot整合Datax数据同步1.简介设计理念 DataX3.0框架设计DataX3.0核心架构核心模块介绍DataX调度流程 2.DataX3.0插件体系3.数据同步1.编写job的json文件2.进入bin目录下&#xff0c;执行文件 4.SpringBoot整合DataX生成Job文件并执…

SAP_MM模块-特殊业务场景下的系统实现方案

一、业务背景 目前公司有一种电商业务&#xff0c;卖的是备品配件&#xff0c;是公司先跟供应商采购&#xff0c;然后再销售给客户&#xff0c;系统账就是按照正常业务来流转&#xff0c;公司进行采购订单入库&#xff0c;然后销售订单出库。 不过这种备品配件&#xff0c;实…

【服务器搭建】✈️用自己电脑搭建一个服务器!

目录 &#x1f44b;前言 &#x1f440;一、内网穿透 &#x1f331;二、内网穿透工具 &#x1f49e;️三、本地测试 3.1 环境准备 3.2 nginx 修改启动页面 3.3 神卓互联注册&#xff0c;创建映射规则 &#x1f4eb;四、章末 &#x1f44b;前言 小伙伴们大家好&#xff0c;一…

【算法笔记自学】第 7 章 提高篇(1)——数据结构专题(1)

7.1栈的应用 #include <iostream> #include <string> #include <stack> using namespace std;int main() {int n, x;string action;cin >> n;stack<int> s;for (int i 0; i < n; i) {cin >> action;if (action "push") {ci…

微信小程序毕业设计-社区门诊管理系统项目开发实战(附源码+论文)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…

从资金管理的角度 谈谈伦敦金投资技巧

刚进入伦敦金市场的时候&#xff0c;笔者认为技术分析是很重要的&#xff0c;所以将学习伦敦金投资技巧的精力全部投入到技术分析的学习中。经过一系列交易的亏损&#xff0c;笔者才发现&#xff0c;其实交易管理才是最重要的。如果管理得好&#xff0c;30%的胜率&#xff0c;投…

Liunx网络配置

文章目录 一、查看网络配置永久修改网卡临时修改网卡 二、查看主机名称 hostname三、查看路由表条目 route四、查看网络连接情况netstat五、获取socket统计信息ss六、查看当前系统中打开的文件和进程的工具lsof七、测试网络连通性ping八、跟踪数据包 traceroute九、域名解析 ns…

一个最简单的comsol斜坡稳定性分析例子——详细步骤

一个最简单的comsol斜坡稳定性分析例子——详细步骤 标准模型例子—详细步骤 线弹性模型下的地应力平衡预应力与预应变、土壤塑性和安全系数求解的辅助扫描

计算机网络之令牌环

1.令牌环工作原理 令牌环&#xff08;Token Ring&#xff09;是一种局域网&#xff08;LAN&#xff09;的通信协议&#xff0c;最初由IBM在1984年开发并标准化为IEEE 802.5标准。在令牌环网络中&#xff0c;所有的计算机或工作站被连接成一个逻辑或物理的环形拓扑结构。网络中…

Kyutai 推出了 Moshi Chat,这是一种既可以实时收听又可以说话的 AI

Kyutai 是一家专注于开放式 AI 研究的非营利性实验室&#xff0c;它推出了开源的 Moshi Chat 项目 Kyutai 是一家致力于推进人工智能 &#xff08;AI&#xff09; 开放研究的非营利性实验室&#xff0c;其最新创新 Moshi Chat 取得了重大进展。这种尖端的实时原生多模态基础模…

STM32-USART

本内容基于江协科技STM32视频学习之后整理而得。 文章目录 1. 串口通信协议1.1 通信接口1.2 串口通信1.3 硬件电路1.4 电平标准1.5 串口参数及时序1.6 串口时序 2. USART串口通信2.1 USART简介2.2 USART框图2.3 USART基本结构2.4 数据帧2.5 数据帧-配置停止位2.6 起始位侦测2.…

dell Vostro 3690安装win11 23h2 方法

下载rufus-4.5.exe刻U盘去除限制 https://www.dell.com/support/home/zh-cn/product-support/product/vostro-3690-desktop/drivers dell官网下载驱动解压到U盘 https://dl.dell.com/FOLDER09572293M/2/Intel-Rapid-Storage-Technology-Driver_88DM9_WIN64_18.7.6.1010_A00_01…

图神经网络dgl和torch-geometric安装

文章目录 搭建环境dgl的安装torch-geometric安装 在跑论文代码过程中&#xff0c;许多小伙伴们可能会遇到一些和我一样的问题&#xff0c;就是文章所需要的一些库的版本比较老&#xff0c;而新版的环境跑代码会报错&#xff0c;这就需要我们手动的下载whl格式的文件来安装相应的…

Django之项目开发(二)

目录 一、安装和使用uWSGI 1.1、安装 1.2、配置文件 1.3、启动与停止uwsgi 二、安装nginx 三、Nginx 配置uWSGI 四、Nginx配置静态文件 五、Nginx配置负载均衡 一、安装和使用uWSGI uWSGI 是一个 Web 服务器,可以用来部署 Python Web 应用。它是一个高性能的通用的 We…

Spring源码十七:Bean实例化入口探索

上一篇Spring源码十六&#xff1a;Bean名称转化我们讨论doGetBean的第一个方法transformedBeanName方法&#xff0c;了解Spring是如何处理特殊的beanName&#xff08;带&符号前缀&#xff09;与Spring的别名机制。今天我们继续往方法下面看&#xff1a; doGetBean 这个方法…

机械键盘如何挑选

机械键盘的选择是一个关键的决策&#xff0c;因为它直接影响到我们每天的打字体验。在选择机械键盘时&#xff0c;有几个关键因素需要考虑。首先是键盘的键轴类型。常见的键轴类型包括蓝轴、红轴、茶轴和黑轴等。不同的键轴类型具有不同的触发力、触发点和声音。蓝轴通常具有明…