高频面试题:什么是B树?为啥文件索引要用B树而不用二叉查找树?

2023-10-29 03:59

本文主要是介绍高频面试题:什么是B树?为啥文件索引要用B树而不用二叉查找树?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

640?wx_fmt=png

来源公众号:苦逼的码农

作者:帅地

一、面试被怼

面试官:你知道文件索引、数据库索引一般用什么数据结构来存储吗?

小秋:知道啊,一般都是用树形结构来存储的。

面试官:可以说说为啥用树形结构来存储吗?

小秋:树形结构例如想 B 树,B+ 树,二叉查找树都是有序的,所以查询效率很高,可以再 O(logn) 的时间复杂度查找到目标数据。

面试官:那可以问问文件索引,例如数据库索引一般用哪种树形结构吗?

小秋:大部分用 B+ 树,少部分用 B 树。(B和B+树太他么复杂了,幸好背了下面试题,嘻嘻)

面试官:想问下为什么要用 B 树而不用二叉查找树啊?或者为啥不用哈希表啊?哈希表的查找速度也很快呀。

小秋:哈希表虽然能够再 O(1) 查找到目标数据,不过如果我们要进行模糊查找的话,却只能遍历所有数据,并且如果出现了极端情况,哈希表冲突的元素太多,也会导致线性时间的查找效率的。

面试官:那为啥不用二叉查找树呢?

小秋:这个…..其实我也不知道,当时是在某个面试题中看到的答案的,嘻嘻。

面试官:那你可以回去等通知了….

二、为啥不用二叉查找树呢?

小秋被怼后有点沮丧,跑过来问帅地关于 B 树的一些知识以及心中的疑问。

小秋:今天去面试,面试问我,为啥文件索引要用 B 树而不用二叉查找树,然后我想了下,感觉如果这是一颗比较平衡的二叉查找树的话,那么查找效率是非常快的,难度 B 树还能比它更快吗?

帅地:确实,如果是查找效率(即比较次数)的话,实际上二叉树可以说是最快的了,但是,我们的文件索引是存放在磁盘上的,所以我们不仅要考虑查找效率,还要考虑磁盘的寻址加载次数哦,而这也是我们为什么要用 B 树的原因。

小秋:难道二叉查找树会导致磁盘的加载次数更多吗?可以给我详细讲讲吗?

帅地:可以呀,不过听懂了,觉得我讲的不错,你要记得给我多点赞,转发哦。

小秋:绝对没问题。

三、什么是 B 树?

帅地:要讲懂这个问题,我们先来了解一下什么是 B 树,其实,B 树和二叉查找树一样,都是B 树相当于是一棵多叉查找树,对于一棵 m 阶的 B 树具有如下特性:

1、根节点至少有两个孩子。

2、每个中间节点都包含 k - 1 个元素和 k 个孩子,其中 m/2 <= k <= m。

3、每一个叶子节点都包含 k - 1 个元素,其中 m/2 <= k <= m。

4、所有的叶子节点都位于同一侧。

5、每个节点中的元素从小到大排列,节点当中的 k - 1 个元素正好是 k 个孩子包含的元素的值域划分。

小秋:我去,这么复杂,鬼才记得住,我还是选择不学了,呜呜。

帅地:你别着急,这些规则我也记不住,只是让你大致知道一些这些规则,一般情况下,我们并不需要把它的规则完全背起来滴。为了加深理解,我给你举个 B 树的例子吧。例如:

640?wx_fmt=png

图中是一棵m = 3 的 3 阶 B 树,可以看出,树中有些节点是有多个元素的,并且和二叉查找树一样,左节点的所有元素的值都比父亲元素小。例如对于(3, 7)这个节点。两个元素把这个节点分割成三个值域,即可以有 3 个孩子。2 相当于 3 的左孩子节点,而 (4,6)相当于 3 的右孩子,同时也是 7 的左孩子,而 9 是 7 的右孩子。

和二叉查找树还是很相似滴,都是有序,且左孩子小,右孩子大,只是 B 树的一个节点可以有多个元素,并且有多个分支。而这些分支以及元素的数量规则,可以从上面的五个规则中查找哈。说实话,我也懒的记那些规则,只知道个大概以及 B 树的应用即可。

文章来源于微信公众:『苦逼的码农』,更多文章可搜索关注

四、小秋的疑惑

小秋:我知道了,不过这种多叉的树,真的可以比二叉查找树效率更好吗,我怎么觉得不可以呢?

帅地:那你可以说说哦。

小秋:例如,上面的 B 树有 11 个元素,按照这 11 个元素,我们建立一个如下的二叉查找树,如图(我去,这个图片了好长时间,ppt 画的)

640?wx_fmt=png

下面我们来进行查询效率比较

1、在 B 树中的查找次数4次比较,例如:

640?wx_fmt=png

第二、三次比较:和 3 比较,比 3 大,这个时候我们还得和 7 比较。

640?wx_fmt=png

第四次比较:和 9 比较,相等,找到目标树,返回。

640?wx_fmt=png

所以最终的结果需要 4 次比较。

2、在二叉树的比较结果

为了节省篇幅,我就不逐个比较了,相信你也一眼就看出来了,也是需要 4 次比较。如图

640?wx_fmt=png

小秋:同样都是四次比较,而且,B 树的每一个节点,如果存放的元素比较多,那么 B 树的比较次数会更多,为什么就说 B 的效率比 二叉查找树快呢?

五、解决疑惑

帅地:确实,如果单单从比较次数看的话,二叉查找树确实不比 B 树差,不过你忽略了一个很重要的点,那就是磁盘的寻址加载次数

我们知道,在把磁盘里的数据加载到内存中的时候,是以为单位来加载的,而我们也知道,节点与节点之间的数据是不连续的,所以不同的节点,很有可能分布在不同的磁盘页中。所以对于上面的二叉查找树,我们可能需要进行 4 次寻址加载,如图:

640?wx_fmt=png

而对于 B 树,由于 B 树的每一个节点,可以存放多个元素,所以磁盘寻址加载的次数会比较少,例如上面的例子中,用 B 树的话,只需要加载 3 次,如图:

640?wx_fmt=png

我们都知道,在内存的运算速度是非常快的,至少比磁盘的寻址加载速度,快了几百倍,而我们进行数值比较的时候,是在内存中进行的,虽然 B 树的比较次数可能比二叉查找树多,但是磁盘操作次数少,所以总体来说,还是 B 树快的多,这也是为什么我们用使用 B 树来存储的原因。

小秋:原来这样啊,以前一直蒙在鼓里。

文章来源于微信公众:『苦逼的码农』,更多文章可搜索关注

帅地:不知道你发现没有,实际上磁盘的加载次数,基本上是和树的高度相关联的,高度越高,加载次数越多,越矮,加载次数越少。所以对于这种文件索引的存储,我们一般会选择矮胖的树形结构。例如有 1000 个元素,如果是二叉查找树的话,高度可能高达 10 层,而如果用 10 阶 B 树的话,只需要三四层即可。

小秋:终于搞懂了,不过我还有个疑问,大部分文件索引或者数据库索引都是用 B+ 树的,而只有小部分才用 B 树,可以问下为什要用 B+ 树而不用 B 树吗?还有,B 树还有其他的应用吗?

帅地:B 树除了会用在少部分的文件索引(数据库索引)外,应用的最多的就是文件系统了。至于为什么要用 B 树而不用 B+ 树,为什么数据库索引大部分用 B+ 树而不用 B 树,我们下节再讲了。

小秋:那我期待着。

帅地:如果觉得有收获,可以帮忙多多转发,点赞,分享哦,这也是我写文章的动力来源。

总结

关于 B 树和 B+ 树,在面试的过程中,还是问的挺多滴,特别是问到数据库的时候,基本会问索引,进而问到 B+ 树,从而也会扯到 B 树。所以掌握着两种树的应用以及原理,是非常重要的,虽然他们的规则很复杂,但是如果是应付面试等,其实不需要背那些规则,只需要知道大概以及知道他们的原理即可。

推荐阅读

640?wx_fmt=png

这篇关于高频面试题:什么是B树?为啥文件索引要用B树而不用二叉查找树?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/298115

相关文章

oracle数据库索引失效的问题及解决

《oracle数据库索引失效的问题及解决》本文总结了在Oracle数据库中索引失效的一些常见场景,包括使用isnull、isnotnull、!=、、、函数处理、like前置%查询以及范围索引和等值索引... 目录oracle数据库索引失效问题场景环境索引失效情况及验证结论一结论二结论三结论四结论五总结ora

Python中列表的高级索引技巧分享

《Python中列表的高级索引技巧分享》列表是Python中最常用的数据结构之一,它允许你存储多个元素,并且可以通过索引来访问这些元素,本文将带你深入了解Python列表的高级索引技巧,希望对... 目录1.基本索引2.切片3.负数索引切片4.步长5.多维列表6.列表解析7.切片赋值8.删除元素9.反转列表

MySQL的索引失效的原因实例及解决方案

《MySQL的索引失效的原因实例及解决方案》这篇文章主要讨论了MySQL索引失效的常见原因及其解决方案,它涵盖了数据类型不匹配、隐式转换、函数或表达式、范围查询、LIKE查询、OR条件、全表扫描、索引... 目录1. 数据类型不匹配2. 隐式转换3. 函数或表达式4. 范围查询之后的列5. like 查询6

PostgreSQL如何查询表结构和索引信息

《PostgreSQL如何查询表结构和索引信息》文章介绍了在PostgreSQL中查询表结构和索引信息的几种方法,包括使用`d`元命令、系统数据字典查询以及使用可视化工具DBeaver... 目录前言使用\d元命令查看表字段信息和索引信息通过系统数据字典查询表结构通过系统数据字典查询索引信息查询所有的表名可

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

荣耀嵌入式面试题及参考答案

在项目中是否有使用过实时操作系统? 在我参与的项目中,有使用过实时操作系统。实时操作系统(RTOS)在对时间要求严格的应用场景中具有重要作用。我曾参与的一个工业自动化控制项目就采用了实时操作系统。在这个项目中,需要对多个传感器的数据进行实时采集和处理,并根据采集到的数据及时控制执行机构的动作。实时操作系统能够提供确定性的响应时间,确保关键任务在规定的时间内完成。 使用实时操作系统的

一些其他面试题

阿里二面:那你来说说定时任务?单机、分布式、调度框架下的定时任务实现是怎么完成的?懵了。。_哔哩哔哩_bilibili 1.定时算法 累加,第二层每一个格子是第一层的总时间400 ms= 20 * 20ms 2.MQ消息丢失 阿里二面:高并发场景下引进消息队列有什么问题?如何保证消息只被消费一次?真是捏了一把汗。。_哔哩哔哩_bilibili 发送消息失败

zookeeper相关面试题

zk的数据同步原理?zk的集群会出现脑裂的问题吗?zk的watch机制实现原理?zk是如何保证一致性的?zk的快速选举leader原理?zk的典型应用场景zk中一个客户端修改了数据之后,其他客户端能够马上获取到最新的数据吗?zk对事物的支持? 1. zk的数据同步原理? zk的数据同步过程中,通过以下三个参数来选择对应的数据同步方式 peerLastZxid:Learner服务器(Follo

java常用面试题-基础知识分享

什么是Java? Java是一种高级编程语言,旨在提供跨平台的解决方案。它是一种面向对象的语言,具有简单、结构化、可移植、可靠、安全等特点。 Java的主要特点是什么? Java的主要特点包括: 简单性:Java的语法相对简单,易于学习和使用。面向对象:Java是一种完全面向对象的语言,支持封装、继承和多态。跨平台性:Java的程序可以在不同的操作系统上运行,称为"Write once,

Verybot之OpenCV应用二:霍夫变换查找圆

其实我是想通过这个程序来测试一下,OpenCV在Verybot上跑得怎么样,霍夫变换的原理就不多说了,下面是程序: #include "cv.h"#include "highgui.h"#include "stdio.h"int main(int argc, char** argv){cvNamedWindow("vedio",0);CvCapture* capture;i