数据结构与算法----问答2023

news/2024/4/19 11:02:28/文章来源:https://blog.csdn.net/qq_45908742/article/details/129087958

在这里插入图片描述

1、什么是哈希表?如何解决碰撞?

哈希表(Hash Table),也称为散列表,是一种用于实现字典(键值对)数据结构的数据结构。它将键映射到哈希表中的一个索引(桶)来保存值。哈希表的主要优势在于它的查找、插入和删除操作的平均时间复杂度为 O(1)。

哈希表的实现通常基于一个哈希函数,它将键映射到一个固定大小的索引范围内(通常是数组的大小)。当两个或多个键被映射到相同的索引时,就会发生碰撞。碰撞是哈希表实现中需要解决的一个主要问题。

哈希表解决碰撞的主要方法有两种:

链接法(Chaining):每个桶存储一个链表,当发生碰撞时,新的键值对可以添加到链表的末尾。这种方法的缺点是链表需要额外的内存来存储,同时在链表中查找或删除一个键值对的平均时间复杂度可能会增加。开放地址法(Open Addressing):当发生碰撞时,新的键值对可以使用一种探测序列来寻找下一个可用的桶。这种方法的优点是没有额外的内存开销,同时可以更好地利用缓存,但是需要仔细选择探测序列,以便尽可能快地找到下一个可用的桶。开放地址法还可以分为线性探测、二次探测、双重散列等多种方式。

2、

3、vector中的size和capacity的区别?

在C++ STL中的vector容器中,size和capacity是两个不同的概念:

size:vector容器中存储的实际元素数量。capacity:vector容器中分配的内存空间的大小,即当前vector容器最多可以存储多少个元素。

当vector容器中存储的元素数量超过了当前分配的内存空间大小时,vector容器会自动扩容,分配一块更大的内存空间,并将原有的元素拷贝到新的内存空间中。因此,capacity通常大于或等于size。

在vector中,size()函数返回vector容器中实际存储的元素数量,而capacity()函数返回当前分配的内存空间大小,即当前vector容器最多可以存储的元素数量。

4、数组和链表的区别?

数组和链表是常用的两种数据结构,它们在实现和使用上有很大的不同。

实现方式:

数组是一种顺序存储结构,其元素在内存中是连续存储的,数组的大小在创建时就需要预先指定。

链表是一种动态存储结构,其元素在内存中可以不连续,每个节点通常包含一个数据元素和一个指向下一个节点的指针。

插入和删除操作:

数组的插入和删除操作较为麻烦,因为数组的大小是固定的,如果需要在中间插入或删除元素,就需要移动其他元素,效率较低。

链表的插入和删除操作比较简单,只需要修改指针即可。在链表中插入或删除一个元素的时间复杂度为O(1)。

访问操作:

数组的访问操作很快,可以通过下标直接访问数组中的元素,时间复杂度为O(1)。

链表的访问操作比较耗时,需要遍历整个链表,时间复杂度为O(n),其中n是链表的长度。

内存占用:

由于数组的元素在内存中是连续存储的,因此它的空间利用率比链表要高,但是当数组的大小超过预分配的内存时,需要重新分配内存,这样就可能会浪费一些内存空间。

链表的元素在内存中不一定是连续存储的,因此它的空间利用率较低,但是链表可以动态地分配内存,不会浪费太多内存空间。

综上所述,数组和链表各有优缺点,应根据实际情况选择适合的数据结构。通常情况下,如果需要高效的随机访问元素,可以选择数组;如果需要高效的插入和删除操作,可以选择链表。

5、map的底层实现?

在C++ STL中,map是一种关联容器,其底层实现通常使用红黑树(Red-Black Tree)来实现。红黑树是一种自平衡的二叉搜索树,可以在O(log n)的时间复杂度内进行插入、查找、删除等操作,保证了map容器的高效性能。

红黑树的基本性质:

每个节点不是红色就是黑色。
根节点是黑色的。
每个叶子节点(NIL节点,空节点)是黑色的。
如果一个节点是红色的,则它的两个子节点都是黑色的。
对于每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点。

红黑树的插入、删除等操作都是通过旋转和改变节点颜色等方式来实现的,以保证红黑树始终满足上述基本性质。

在实际使用中,map容器可以存储键值对,并且会根据键的大小进行排序。当使用operator[]访问map中的元素时,会进行一次查找操作,时间复杂度为O(log n)。

总之,map容器采用红黑树作为底层实现,保证了高效的插入、查找、删除等操作,并且可以自动排序,是一种非常实用的数据结构。

6、迭代器失效问题?

迭代器失效是指在使用迭代器遍历容器时,由于容器的修改操作导致迭代器指向的元素或者容器本身被删除或者移动,从而使得该迭代器无法再正确访问容器中的元素或者指向的位置变得不确定。

迭代器失效问题是容器使用中常见的一个问题,主要有以下几种情况:

插入元素导致迭代器失效

在插入元素时,可能会导致原有元素的位置发生改变,从而使得迭代器失效。比如,当向vector中插入元素时,如果vector的大小已经达到了它的capacity,那么vector会重新分配内存并将原有元素复制到新的内存空间中,从而导致原有迭代器失效。

删除元素导致迭代器失效

在删除元素时,可能会导致原有元素的位置发生改变,从而使得迭代器失效。比如,当使用list容器的erase()函数删除元素时,该元素后面的所有元素的位置都会向前移动一个位置,从而导致原有迭代器失效。

改变容器大小导致迭代器失效

在改变容器的大小时,可能会导致容器内部的元素位置发生改变,从而使得迭代器失效。比如,当使用vector容器的resize()函数改变容器大小时,如果容器的大小变小,那么位于容器末尾后面的元素会被删除,从而导致原有迭代器失效。

为了避免迭代器失效问题,一般建议在进行容器的修改操作前,先将需要访问的元素复制到另一个容器中,修改后再将其复制回原容器。此外,也可以使用一些容器操作函数的返回值来避免迭代器失效问题,比如使用list容器的erase()函数返回删除元素后的迭代器。

7、冒泡排序和快速排序的时间复杂度?实现原理?

冒泡排序

冒泡排序是一种简单的排序算法,它的基本思想是将待排序的元素两两比较,将较大的元素向后移动,直到最大的元素移动到数组的末尾。冒泡排序的时间复杂度为O(n^2)。

实现原理:

遍历数组,对于数组中的每一个元素,都和它后面的元素比较。
如果当前元素比后面的元素大,则交换它们的位置,使较大的元素向后移动。
重复上述操作,直到所有元素都按照从小到大的顺序排好

快速排序

快速排序是一种基于分治的排序算法,它的基本思想是选定一个基准元素,将数组分成两部分,使左边的元素都小于等于基准元素,右边的元素都大于等于基准元素。然后递归地对左右两部分进行快速排序。快速排序的时间复杂度为O(nlogn)。

实现原理:

选取一个基准元素,通常选择数组的第一个元素或最后一个元素。
从数组的两端开始搜索,找到第一个比基准元素大的元素和第一个比基准元素小的元素,然后交换它们的位置。
继续从上一步停止的位置开始搜索,直到搜索完整个数组。
将基准元素与搜索结束时第一个比基准元素小的元素交换位置,这样基准元素就位于数组的中间位置,左边的元素都小于等于它,右边的元素都大于等于它。
递归地对左右两部分进行快速排序。

冒泡排序和快速排序都是常见的排序算法,冒泡排序简单但时间复杂度高,适合用于小规模数据的排序;而快速排序虽然复杂一些,但时间复杂度较低,适合用于大规模数据的排序。

8、算法-反转字符串?

9、算法-二叉树的最近公共祖先?

10、vector 和 list的区别?

vector和list是两种常见的C++容器,它们之间有以下区别:

底层实现不同

vector底层使用的是连续的内存空间,通过数组实现。而list底层使用的是双向链表,通过指针实现。

随机访问效率不同

由于vector底层使用的是数组,所以它可以通过下标随机访问元素,时间复杂度为O(1);而list不支持下标访问,只能通过迭代器进行顺序访问,时间复杂度为O(n)。

插入和删除效率不同

由于vector底层使用的是数组,当在中间位置插入或删除元素时,需要将后面的元素都往后或往前移动,时间复杂度为O(n);而list由于底层是链表结构,插入或删除元素只需要改变相邻节点的指针指向,时间复杂度为O(1)。

内存使用效率不同

由于vector底层使用的是数组,它需要预分配一定大小的内存空间,在需要扩容时需要重新分配内存并将原有元素复制到新的内存空间中,导致内存空间的浪费;而list由于底层是链表结构,它的内存使用效率相对较高。

根据具体的需求,选择不同的容器可以使得代码更高效、更易于实现。比如,当需要随机访问元素时,可以使用vector;当需要频繁插入和删除元素时,可以使用list。

11、红黑树的特点?

红黑树是一种自平衡的二叉查找树,它具有以下特点:

节点是红色或黑色。根节点是黑色,所有叶子节点(NIL节点)都是黑色。每个红色节点的两个子节点都是黑色的,即不存在连续的红色节点。从任意一个节点到其叶子节点的所有路径都包含相同数目的黑色节点。新插入的节点都是红色的。通过旋转和变色操作来维持红黑树的平衡。

红黑树的这些特点保证了它的平衡性和搜索效率。在红黑树中,每个节点最多只需要执行两次旋转操作就可以达到平衡,因此其插入、删除、查找等操作的时间复杂度均为O(log n)。

红黑树常用于C++ STL中的set和map等容器的底层实现。

12、二叉搜索树、平衡二叉树和红黑树的区别?

二叉搜索树、平衡二叉树和红黑树都是常用的树形数据结构,它们的主要区别在以下几个方面:

结构不同

二叉搜索树是一种二叉树,每个节点最多有两个子节点,且满足左子节点的值小于父节点的值,右子节点的值大于父节点的值。

平衡二叉树是一种二叉搜索树,但在插入或删除节点时会通过旋转或其他操作来保持平衡,即左右子树的高度差不超过1。

红黑树是一种自平衡的二叉搜索树,它通过将节点标记为红色或黑色,并通过旋转和颜色变换等操作来保持平衡。

平衡性不同

二叉搜索树的平衡性较差,可能会退化为链表,导致查找、插入、删除等操作的时间复杂度为O(n)。

平衡二叉树可以保证左右子树的高度差不超过1,因此查找、插入、删除等操作的时间复杂度为O(log n)。

红黑树通过维护红黑节点的数量和颜色等规则,可以保证树的平衡性,并且旋转和颜色变换等操作比平衡二叉树的旋转操作更少,因此查找、插入、删除等操作的时间复杂度也为O(log n)。

存储结构不同

二叉搜索树的节点结构较简单,通常只需要存储一个值和两个指针。

平衡二叉树和红黑树的节点结构都比较复杂,需要存储额外的信息来维护平衡性或红黑节点规则。

基于上述区别,如果数据的插入和删除操作较少,但需要频繁进行查找,可以选择二叉搜索树;如果插入和删除操作频繁且需要保持平衡,可以选择平衡二叉树;如果需要支持高效的查找、插入和删除操作,并且需要保持平衡,可以选择红黑树。

13、

14、B树和B+树的区别?

B树和B+树都是一种常用的平衡多路查找树,它们的主要区别在于以下几个方面:

节点结构不同

B树的节点通常包含关键字和指向子树的指针,而B+树的节点只包含关键字,所有的数据都存储在叶子节点中。

存储方式不同

B树的节点可以存储数据,也可以不存储数据,数据可以存储在任意一个节点中;而B+树的所有数据都存储在叶子节点中,非叶子节点只用于索引,不存储数据。

叶子节点的链表结构不同

在B树中,所有的叶子节点不需要连接起来形成一个链表,而在B+树中,所有的叶子节点通过指针形成一个有序的链表,方便范围查找。

搜索方式不同

在B树中,如果某个关键字在非叶子节点上被找到,则可以直接通过该节点指向的子树继续查找;而在B+树中,所有的数据都存储在叶子节点中,因此只需要搜索叶子节点即可。

基于上述区别,B树适合随机读取和修改,而B+树适合范围查找和顺序遍历。因此,B+树常用于数据库索引、文件系统等需要支持快速范围查找的应用场景。

15、stl 容器的线程安全性?

STL(标准模板库)中的容器通常不是线程安全的,这意味着如果多个线程同时访问同一个容器,并且至少有一个线程对容器进行了写操作,那么就有可能导致数据竞争和不确定的行为。

在多线程环境下,可以采取以下几种方法来确保容器的线程安全性:

采用互斥锁:在每个线程访问容器之前,先获取一个互斥锁,并在访问完成后释放锁。这种方法可以保证同时只有一个线程访问容器,从而避免数据竞争。采用读写锁:如果读操作比写操作频繁,可以采用读写锁来提高并发性能。读写锁允许多个线程同时进行读操作,但在写操作时会阻塞其他线程的读写操作。使用线程安全的容器:一些库(如C++11及以后版本的标准库)提供了线程安全的容器,这些容器可以同时被多个线程访问,而不需要额外的同步机制。这些容器一般采用锁或其他并发控制机制来保证线程安全性。

16、算法-删除链表的结点?

17、算法-合并两个链表?

18、算法-常用的排序算法,哪些是稳定的?哪些是不稳定的?

19、算法-快速排序的原理和实现?

快速排序(Quick Sort)是一种常用的排序算法,采用分治的思想,通过递归地将数组划分为更小的子数组来实现排序。其核心思想是通过选定一个基准元素,将数组中小于等于该元素的元素放在左边,大于该元素的元素放在右边,然后对左右两个子数组递归地进行排序,最终完成整个数组的排序。

快速排序的实现步骤如下:

选择一个基准元素(pivot),一般选择数组的第一个元素或最后一个元素。
将数组中小于等于基准元素的元素放在左边,大于基准元素的元素放在右边,这个过程叫做分区(partition)。
对左右两个子数组分别递归地进行快速排序。

快速排序的时间复杂度为 O(nlogn),其中 n 为数组长度。在最坏情况下,快速排序的时间复杂度可能会退化到 O(n^2),例如当数组已经有序或逆序时,每次分区只能减少一个元素。为避免这种情况,可以采用随机化快速排序或者其他优化方法。

20、算法-两个栈实现队列?

使用两个栈来实现队列,可以通过将一个栈作为输入栈,另一个栈作为输出栈来完成队列的操作。

具体实现方法如下:

当需要插入一个元素时,将元素压入输入栈中。
当需要删除队首元素时,如果输出栈不为空,直接弹出输出栈的栈顶元素;否则,将输入栈中的所有元素依次弹出并压入输出栈中,然后再弹出输出栈的栈顶元素。

21、汉诺塔是怎么实现的?

使用递归算法,可以很容易地解决汉诺塔问题,其中递归函数hanoi(n, A, B, C)表示将n个盘子从A通过B移动到C的过程:

当n等于1时,直接把盘子从A移动到C;
当n大于1时,先将上面n-1个盘子从A通过C移动到B;
然后将最下面的盘子从A移动到C;
最后将上面n-1个盘子从B通过A移动到C。

22、

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【离线数仓-8-数据仓库开发DWD层-交易域相关事实表】

离线数仓-8-数据仓库开发DWD层-交易域相关事实表离线数仓-8-数据仓库开发DWD层-交易域相关事实表一、DWD层设计要点二、交易域相关事实表1.交易域加购事务事实表1.加购事务事实表 前期梳理2.加购事务事实表 DDL表设计分析3.加购事务事实表 加载数据分析1.首日全量加购的数据加载…

mysys2+minGW方案编译ffmpeg的最佳实践

一、Win10 64bit编译环境的建立1)从http://www.msys2.org/下载 msys2-x86_64-xxx.exe2) 安装msys2到默认路径 C:\msys64\3) 运行MSYS2 w644)执行 pacman -Syu 更新系统当出现提示时,选择y5) 当窗口关闭时,重…

【unity游戏制作-mango的冒险】场景二的镜头和法球特效跟随

👨‍💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 收录于专栏:unity游戏制作 ⭐mango的冒险场景二——镜头和法球特效跟随⭐ 文章目录⭐mango的冒险场景二——镜…

前端:分享JS中7个高频的工具函数

目录 ◆1、将数字转换为货币 ◆2、将 HTML 字符串转换为 DOM 对象 ◆3、防抖 ◆4、日期验证 ◆5、将 FormData(表单数据)转换为 JSON ◆6、衡量一个函数的性能 ◆7、从数组中删除重复项 JavaScript 实用函数是有用的、可重复使用的片段&#xff0…

Kotlin1.8新特性

Kotlin1.8.0新特性 新特性概述 JVM 的新实验性功能:递归复制或删除目录内容提升了 kotlin-reflect 性能新的 -Xdebug 编译器选项,提供更出色的调试体验kotlin-stdlib-jdk7 与 kotlin-stdlib-jdk8 合并为 kotlin-stdlib提升了 Objective-C/Swift 互操作…

FL StudioV21电脑版水果编曲音乐编辑软件

这是一款功能十分丰富和强大的音乐编辑软件,能够帮助用户进行编曲、剪辑、录音、混音等操作,让用户能够全面地调整音频。FL水果最新版是一款专业级别的音乐编曲软件,集合更多的编曲功能为一身,可以进行录音、编辑、制作、混音、调…

5 KNN算法及Python实现

0 建议学时 2学时 1 KNN算法 1.1 KNN原理 KNN:K Nearest Neighbors,即K个最近的邻居; 预测一个新值xxx,根据距离最近的K个点的类别来判断xxx属于哪一类。 算法核心要点: K值的选取非常重要; 距离公式…

数学不好,英语不行,非本专业,可以学IT吗?

很多小伙伴,都会问小青一些比较类似的问题。比如:不是计算机专业的,可以学编程吗?数学一直就不好,可以转行学IT吗?学编程开发,对英语的的要求会不会很高?01计算机不是计算机专业的&a…

【Arduino 无刷电机控制教程】

【Arduino 无刷电机控制教程】 1. 概述2. 试验准备3. 实验原理4. Arduino 无刷电机控制 – 电路图4.1 实验组件4.2 用于 BLDC 电机控制的 Arduino 代码5. 实验验证5.1 电位计控制无刷电机速度5.2 电调校准在本教程中,我们将学习如何使用 Arduino 和 ESC 控制无刷电机。如果您想…

(三)代表性物质点邻域的变形分析

本文主要内容如下:1. 伸长张量与Cauchy-Green 张量2. 线元长度的改变2.1. 初始/当前构型下的长度比2.2. 主长度比与 Lagrange/Euler 主方向2.3. 初始/当前构型下任意方向的长度比3. 线元夹角的改变4. 面元的改变5. 体元的改变1. 伸长张量与Cauchy-Green 张量 由于变…

ABAP 辨析CO|CN|CA|NA|CS|NS|CP|NP

1、文档说明 本篇文档将通过举例,解析字符的比较运算符之间的用法和区别,涉及到的操作符:CO|CN|CA|NA|CS|NS|CP|NP 2、用法和区别 用法总览 以下举例,几乎都使用一个字符变量和一个硬编码字符进行对比的方式,忽略尾…

刚上岸字节测试开发岗,全网最真实的大厂面试真题

首先我来解释一下为什么说是全网最真实的面试题,相信大家也发现软件测试面试题在网上流传也已不少,但是经过仔细查看发现了两个很重要的问题。 第一,网上流传的面试题的答案并不能保证百分百正确。也就是说各位朋友辛辛苦苦花了很多时间准备…

【数据结构趣味多】Map和Set

1.概念及场景 Map和set是一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关。 在此之前,我还接触过直接查询O(N)和二分查询O(logN),这两个查询有很多不足之出,直接查询的速率太低,而二分查…

Servlet笔记(11):Servletcontext对象

1、什么是ServletContext ServletContext是一个全局储存空间,随服务器的生命周期变化, Cookie,Session,ServletContext的区别 Cookie: 存在于客户端的本地文本文件 Session: 存在于服务器的文本文件&#…

在外包公司熬了 3 年终于进了字节,竭尽全力....

其实两年前校招的时候就往字节投了一次简历,结果很明显凉了,随后这个理想就被暂时放下了,但是这个种子一直埋在心里这两年除了工作以外,也会坚持写博客,也因此结识了很多优秀的小伙伴,从他们身上学到了特别…

使用kubeadm 部署kubernetes 1.26.1集群 Calico ToR配置

目录 机器信息 升级内核 系统配置 部署容器运行时Containerd 安装crictl客户端命令 配置服务器支持开启ipvs的前提条件 安装 kubeadm、kubelet 和 kubectl 初始化集群 (master) 安装CNI Calico 集群加入node节点 机器信息 主机名集群角色IP内…

FreeRTOS的Delay函数

两个Delay函数有两个延时函数vTaskDelay:至少等待指定个数的Tick Interrupt才能变为就绪态xTaskDelayUtil:等待到指定的绝对时刻,才能变为就绪态个人感觉这两个延时函数就是,比如一个我等3个小时,一个是我等到下午3点的…

回归预测 | MATLAB实现BO-CNN-BiLSTM贝叶斯优化卷积双向长短期记忆网络数据回归预测

回归预测 | MATLAB实现BO-CNN-BiLSTM贝叶斯优化卷积双向长短期记忆网络数据回归预测 目录回归预测 | MATLAB实现BO-CNN-BiLSTM贝叶斯优化卷积双向长短期记忆网络数据回归预测效果一览基本介绍模型搭建程序设计参考资料效果一览 基本介绍 基于贝叶斯优化卷积双向长短期记忆网络(…

会声会影2023专业版视频处理制作软件功能详细介绍

会声会影是一款专业的视频处理和制作软件,也是目前影楼制作结婚和一般视频特效制作的必备软件,他是一款专为个人及家庭所设计的数码影片编辑软件,可将数 字或模拟摄像机所拍下来的如成长写真、国外旅游、个人MTV、生日派对、毕业典礼等精彩生…

惠普m1136打印机驱动程序安装教程

惠普m113打印机是一款功能强大的多功能打印机,它能够打印、复印、扫描和传真等。如果你要使用这款打印机,你需要下载并安装驱动程序,以确保它能够在你的计算机上正常工作。在本文中,我们将介绍如何下载和安装惠普m1136打印机驱动程…