C++基础面试题
一、vector和list的区别
1.1 底层数据结构
vector 使用动态数组作为底层数据结构,元素在内存中是连续存储的;
list 使用双向链表作为底层数据结构,元素在内存中通过节点相互连接。
1.2 插入和删除操作
vector 在尾部插入或删除元素效率高,但在中间或头部插入/删除元素时需要移动后续元素,效率较低;
list 在任意位置插入或删除元素的效率都很高,因为它只需修改相邻节点的指针。
1.3 随机访问
vector允许通过下标进行快速随机访问,因为元素在内存中是连续的;
list不支持随机访问,访问元素需要从头结点开始遍历列表,效率较低。
1.4 内存分配
vector需要预先分配一块连续内存,如果元素数量动态增长,可能需要重新分配内存,导致内存浪费或复制操作;
list在插入或释放时只需分配或释放对应节点的内存,内存占用相对较小。
二、vector删除元素、删除区间的理解,erase返回什么?
C++的标准库中,std::vector是一个动态数组容器,你可以使用erase函数来删除单个元素或一个区间内的元素。erase函数的返回值是指向被删除元素之后的迭代器,或者如果删除的是最后一个元素,则返回end()。
如下例子所示:
#include <iostream>
#include <vector>int main() {std::vector<int> numbers = {1, 2, 3, 4, 5};// 删除单个元素std::vector<int>::iterator it = numbers.begin() + 2;it = numbers.erase(it); // 删除索引为2的元素(值为3)for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl;// 删除一个区间std::vector<int>::iterator first = numbers.begin() + 1;std::vector<int>::iterator last = numbers.begin() + 3;numbers.erase(first, last); // 删除区间[1, 3)for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
首先删除了索引为2的元素(值为3),erase返回的迭代器指向被删除元素之后的位置,所以此时it指向了原来的索引为3的元素。然后,我们删除了区间[1, 3)内的元素,即索引1和2的元素,最终得到修改后的numbers。
三、数组和链表区别(相当于是对第一题的详细解释)?
3.1 存储方式
a. 数组:数组是一种连续的存储结构,元素在内存中按线性顺序排列,这使得数组支持随机访问,可以通过索引快速访问任何元素;
b.链表:链表是一种非连续的存储结构,元素以节点的形式存在,每个节点包含数据和指向下一个节点的指针;链表不支持随机访问,必须从头节点开始遍历才能找到特定元素。
3.2 大小固定性
a.数组:数组的大小通常是固定的,一旦分配内存空间,极不容易动态扩展或缩小,此时可通过动态数组来解决,如std::vector;
b.链表 链表大小可以动态增减,节点可以根据需要进行动态分配和释放。
3.3 插入和删除
a.数组:在数组中插入或删除元素通常需要移动其他元素,这可能涉及到大量的数据搬迁,导致性能下降;
b.链表:在链表中插入或删除元素只需要调整节点的指针,不需要移动大量的数据,因此插入和删除操作通常更高效。
四、单向链表,如何找到中间的节点
可使用双指针技巧,其中一个指针每次移动一个节点,另一个指针每次移动两个节点。当快指针到达链表尾部时,慢指针就会指向链表的中间节点。
参考代码如下:
#include <iostream>struct ListNode {int data;ListNode* next;ListNode(int val) : data(val), next(nullptr) {}
};ListNode* findMiddle(ListNode* head) {if (head == nullptr) {return nullptr;}ListNode* slow = head;ListNode* fast = head;while (fast != nullptr && fast->next != nullptr) {slow = slow->next; // 慢指针每次移动一个节点fast = fast->next->next; // 快指针每次移动两个节点}return slow;
}int main() {// 创建一个单链表:1 -> 2 -> 3 -> 4 -> 5ListNode* head = new ListNode(1);head->next = new ListNode(2);head->next->next = new ListNode(3);head->next->next->next = new ListNode(4);head->next->next->next->next = new ListNode(5);// 找到中间节点ListNode* middle = findMiddle(head);if (middle != nullptr) {std::cout << "中间节点的值为: " << middle->data << std::endl;} else {std::cout << "链表为空或长度为偶数,没有中间节点。" << std::endl;}// 释放链表内存while (head != nullptr) {ListNode* temp = head;head = head->next;delete temp;}return 0;
}
五、时间复杂度的概念,如何计算
时间复杂度通常用大O符号(O)来表示,表示算法的运行时间与输入规模之间的增长关系。常见的时间复杂度包括 O(1)、O(log n)、O(n)、O(n log n)、O(n2)、O(2n) 等。
5.1:O(1) - 常数时间复杂度:算法的运行时间是常数,与输入规模无关。例如,访问数组中的元素。
5.2:O(log n) - 对数时间复杂度:算法的运行时间随输入规模呈对数增长。例如,二分查找。
5.3:O(n) - 线性时间复杂度:算法的运行时间与输入规模成正比。例如,遍历数组。
5.4:O(n log n) - 线性对数时间复杂度:算法的运行时间随输入规模呈 n log n 增长。例如,快速排序和归并排序。
5.5:O(n^2) - 平方时间复杂度:算法的运行时间与输入规模的平方成正比。例如,简单的嵌套循环。
5.6:O(2^n) - 指数时间复杂度:算法的运行时间随输入规模成指数级增长。例如,暴力解法。
计算时间复杂度通常涉及分析算法中的循环和递归结构。你需要考虑算法中执行次数最多的那部分代码,并用输入规模 n 来表示。在分析过程中,通常忽略常数因子和低阶项,只关注增长最快的项,因为它们在大规模数据下占主导地位。
六、归并排序算法的实现
流程:
6.1、将待排序数组分为两半,直到每个子数组只包含一个元素。
6.2、递归地对左半部分和右半部分进行排序。
6.3、合并两个有序子数组为一个大的有序数组。
例:
#include <iostream>
#include <vector>// 合并两个有序数组为一个有序数组
void merge(std::vector<int>& arr, int left, int middle, int right) {int n1 = middle - left + 1;int n2 = right - middle;std::vector<int> leftArr(n1);std::vector<int> rightArr(n2);// 将数据拷贝到左右两个子数组中for (int i = 0; i < n1; i++) {leftArr[i] = arr[left + i];}for (int i = 0; i < n2; i++) {rightArr[i] = arr[middle + 1 + i];}// 归并过程int i = 0, j = 0, k = left;while (i < n1 && j < n2) {if (leftArr[i] <= rightArr[j]) {arr[k] = leftArr[i];i++;} else {arr[k] = rightArr[j];j++;}k++;}// 处理剩余元素while (i < n1) {arr[k] = leftArr[i];i++;k++;}while (j < n2) {arr[k] = rightArr[j];j++;k++;}
}// 归并排序主函数
void mergeSort(std::vector<int>& arr, int left, int right) {if (left < right) {int middle = left + (right - left) / 2;// 递归排序左右两半mergeSort(arr, left, middle);mergeSort(arr, middle + 1, right);// 合并已排序的两部分merge(arr, left, middle, right);}
}int main() {std::vector<int> arr = {38, 27, 43, 3, 9, 82, 10};int n = arr.size();std::cout << "Original Array: ";for (int num : arr) {std::cout << num << " ";}std::cout << std::endl;mergeSort(arr, 0, n - 1);std::cout << "Sorted Array: ";for (int num : arr) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
七、如何对排好序的数组去除重复元素?
流程:
7.1 初始化两个指针,一个指向当前元素,另一个指向下一个元素。
7.2 检查当前元素和下一个元素是否相等。
7.3 如果相等,将下一个元素删除,继续检查下一个元素,直到找到不同的元素。
7.4 如果不同,将第一个指针移到下一个位置,继续检查下一个元素。
#include <vector>std::vector<int> removeDuplicates(std::vector<int>& sortedArray) {int n = sortedArray.size();if (n <= 1) {return sortedArray; // 如果数组为空或只有一个元素,无需去重}int index = 0; // 用于记录非重复元素的位置for (int i = 1; i < n; i++) {if (sortedArray[i] != sortedArray[index]) {index++;sortedArray[index] = sortedArray[i];}}sortedArray.resize(index + 1); // 调整数组大小,去除重复元素后的大小return sortedArray;
}int main() {std::vector<int> sortedArray = {1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 6};std::cout << "原始数组:";for (int num : sortedArray) {std::cout << num << " ";}std::cout << std::endl;sortedArray = removeDuplicates(sortedArray);std::cout << "去除重复后的数组:";for (int num : sortedArray) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
相关文章:
C++基础面试题
一、vector和list的区别 1.1 底层数据结构 vector 使用动态数组作为底层数据结构,元素在内存中是连续存储的; list 使用双向链表作为底层数据结构,元素在内存中通过节点相互连接。 1.2 插入和删除操作 vector 在尾部插入或删除元素效率高&…...
asp.net人事管理信息系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio
一、源码特点 asp.net 人事管理信息系统是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言 开发 asp.net 人事管理系统1 应用技术…...
【Docker】Docker中 的AUFS、BTRFS、ZFS、存储池概念的详细讲解
前言 作者简介: 辭七七,目前大二,正在学习C/C,Java,Python等 作者主页: 七七的个人主页 文章收录专栏: 七七的闲谈 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖&…...
华为云运维小结
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、pandas是什么? 一、pandas是什么? HCIP学习笔记-华为云运维方案-9:https://blog.csdn.net/GoNewWay/article/details/13152…...
Firefox 119 正式发布
Firefox 119 已正式发布。新版本除了修复 Bug 之外,还增强了 Firefox View 功能、支持在 PDF 文档中插入图片,以及引入 Encrypted Client Hello (ECH) 以增强隐私保护等。 主要变化 改进 Firefox View:用户可以在该页面查看所有窗口打开的标…...
apachesolr启动带调试
这里solr.cmd报错,报错原因是java版本问题,后面发现这是因为多个java版本导致读取java_home失败, 那么我们修改solr.cmd中的JAVA_HOME为SOLR_JAVA_HOME IF DEFINED SOLR_JAVA_HOME set "JAVA_HOME%SOLR_JAVA_HOME%"环境变量将SOLR…...
【MATLAB】基于灰狼优化算法优化BP神经网络 (GWO-BP)的数据回归预测
文章目录 效果一览文章概述订阅专栏只能获取一份代码部分源码参考资料效果一览 文章概述 【MATLAB】基于灰狼优化算法优化BP神经网络 (GWO-BP)的数据回归预测 在MATLAB中,基于灰狼优化算法优化BP神经网络(GWO-BP)进行数据回归预测的步骤如下: 数据准备:首先,将用于回归预…...
雨水收集设施模块把雨水收集起来,经简单处理用于消防洗车冲厕等
雨水收集设施模块是一种利用雨水资源的环保设施,它可以将雨水收集起来,经过简单的处理后,用于消防、洗车、冲厕等用途。 雨水收集设施模块通常由多个雨水收集器组成,每个收集器都有一个集水口和一个小型储水池。当雨水流入集水口…...
Mac机RVM安装,手动下载安装,经过验证可以正常使用
1、正常方法(不容易成功),我自己就卡了两周(因为墙的问题一直搞不定) 中国境内访问 https://rvm.io 虽然可以访问,但是下载使用会被强,可能有一些翻越的方法,但是不容易搞 2、手…...
人工智能-深度学习之延后初始化
到目前为止,我们忽略了建立网络时需要做的以下这些事情: 我们定义了网络架构,但没有指定输入维度。 我们添加层时没有指定前一层的输出维度。 我们在初始化参数时,甚至没有足够的信息来确定模型应该包含多少参数。 有些读者可…...
Jupyter Notebook交互式开源笔记本工具
1、官网 http://jupyter.org/ 2、什么是Jupyter Notebook Jupyter Notebook一个交互式的开源笔记本工具,可以用于编写、运行、和共享代码、文本、图形等内容。 如下文本、代码、图形 支持多种编程语言,包括python、R和Julia等,可以走一个…...
基于晶体结构算法的无人机航迹规划-附代码
基于晶体结构算法的无人机航迹规划 文章目录 基于晶体结构算法的无人机航迹规划1.晶体结构搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用晶体结构算法来优化无人机航迹规划。 …...
刷题笔记day11-栈与队列2
20. 有效的括号 这个是典型的使用栈,来进行匹配。 因为栈是先进后出,所以,最近的左括号一定在栈顶。如果不是,则就是不匹配了。 func isValid(s string) bool {stack : Stack{}dict : map[byte]byte {): (,]: [,}: {,}for _, it…...
ngixn的指令
Nginx是一个高性能的HTTP和反向代理服务器,它可以处理静态资源、动态内容、负载均衡、反向代理和HTTP缓存等任务。本文将详细介绍在CentOS上安装和配置Nginx服务器,并讲解Nginx常用指令。 安装Nginx 在CentOS上安装Nginx非常简单,只需要执行…...
管理类联考——数学——汇总篇——知识点突破——代数——函数、方程——记忆
文章目录 考点记忆/考点汇总——按大纲 整体局部 本篇思路:根据各方的资料,比如名师的资料,按大纲或者其他方式,收集/汇总考点,即需记忆点,在通过整体的记忆法,比如整体信息很多,通常…...
2014年亚太杯APMCM数学建模大赛C题公共基础课教师专业化培养方式研究求解全过程文档及程序
2014年亚太杯APMCM数学建模大赛 C题 公共基础课教师专业化培养方式研究 原题再现 近年来,世界基础工业、信息产业、服务业的跨越式发展引发了大量人才需求,导致了职业教育的飞速发展,除原有专科层次高等职业教育院校外,大量普通…...
【广州华锐互动】VR历史古城复原:沉浸式体验古代建筑,感受千年风华!
在科技日新月异的今天,虚拟现实(VR)技术已经成为了我们生活中不可或缺的一部分。从娱乐游戏到医疗健康,从教育培训到房地产销售,VR技术的应用领域日益广泛。而近年来,VR技术在文化遗产保护和古迹复原方面的…...
http和https分别是什么?
HTTP(Hypertext Transfer Protocol)和HTTPS(HTTP Secure)是互联网上应用最为广泛的两类协议,都是用于在网络中进行数据交换。 1.HTTP: HTTP是一种无状态的协议,即服务器并不保持与客户端的连接…...
C语言--一个球从100m高度自由落下,每次落地后反弹回原高度的一半,再落下,再反弹。求它在第10次落地时共经过多少米,第10次反弹多高
一.思路分析 这是一个简单的物理题目,解题思路比较明确。程序使用 for 循环来模拟球的下落和反弹过程,通过多次计算得到最终结果,最后使用 printf 函数将结果输出。 定义初始高度 height 和总共经过的米数 distance 的变量,初始化…...
基础知识:位运算
基础知识:位运算 1. 两类表达式2. 项目中用到位运算的🌰 1. 两类表达式 2. 项目中用到位运算的🌰 在一个表中增加一个字段,控制报餐的6个字段包括午餐、晚餐、夜餐1、夜餐2、白班、晚班。正常在表中需要增加6个字段来做开关&…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...
AWS vs 阿里云:功能、服务与性能对比指南
在云计算领域,Amazon Web Services (AWS) 和阿里云 (Alibaba Cloud) 是全球领先的提供商,各自在功能范围、服务生态系统、性能表现和适用场景上具有独特优势。基于提供的引用[1]-[5],我将从功能、服务和性能三个方面进行结构化对比分析&#…...
Selenium 查找页面元素的方式
Selenium 查找页面元素的方式 Selenium 提供了多种方法来查找网页中的元素,以下是主要的定位方式: 基本定位方式 通过ID定位 driver.find_element(By.ID, "element_id")通过Name定位 driver.find_element(By.NAME, "element_name"…...
C#最佳实践:为何优先使用as或is而非强制转换
C#最佳实践:为何优先使用as或is而非强制转换 在 C# 的编程世界里,类型转换是我们经常会遇到的操作。就像在现实生活中,我们可能需要把不同形状的物品重新整理归类一样,在代码里,我们也常常需要将一个数据类型转换为另…...
