面试官:你知道文件索引、数据库索引通常用什么数据结构来存储吗?面试
小秋:知道啊,通常都是用树形结构来存储的。算法
面试官:能够说说为啥用树形结构来存储吗?数据库
小秋:树形结构例如想 B 树,B+ 树,二叉查找树都是有序的,因此查询效率很高,能够再 O(logn) 的时间复杂度查找到目标数据。微信
面试官:那能够问问文件索引,例如数据库索引通常用哪一种树形结构吗?数据结构
小秋:大部分用 B+ 树,少部分用 B 树。(B和B+树太他么复杂了,幸亏背了下面试题,嘻嘻)工具
面试官:想问下为什呀要用 B 树而不用二叉查找树啊?或者为啥不用哈希表啊?哈希表的查找速度也很快呀。开发工具
小秋:哈希表虽然可以再 O(1) 查找到目标数据,不过若是咱们要进行模糊查找的话,却只能遍历全部数据,而且若是出现了极端状况,哈希表冲突的元素太多,也会致使线性时间的查找效率的。3d
面试官:那为啥不用二叉查找树呢?cdn
小秋:这个…..其实我也不知道,当时是再某个面试题中看到的答案的,嘻嘻。视频
面试官:那你能够回去等通知了….
小秋被怼后有点沮丧,跑过来问帅地关于 B 树的一些知识以及心中的疑问。
小秋:今天去面试,面试问我,为啥文件索引要用 B 树而不用二叉查找树,而后我想了下,感受若是这是一颗比较平衡的二叉查找树的话,那么查找效率是很是快的,难度 B 树还能比它更快吗?
帅地:确实,若是是查找效率(即比较次数)的话,实际上二叉树能够说是最快的了,可是,咱们的文件索引是存放在磁盘上的,因此咱们不只要考虑查找效率,还要考虑磁盘的寻址加载次数哦,而这也是咱们为何要用 B 树的缘由。
小秋:难道二叉查找树会致使磁盘的加载次数更多吗?能够给我详细讲讲吗?
帅地:能够呀,不过听懂了,以为我讲的不错,你要记得给我多点赞,转发哦。
小秋:绝对没问题。
帅地:要讲懂这个问题,咱们先来了解一下什么是 B 树,其实,B 树和二叉查找树同样,都是树,B 树至关因而一棵多叉查找树,对于一棵 m 阶的 B 树具备以下特性:
一、根节点至少有两个孩子。
二、每一个中间节点都包含 k - 1 个元素和 k 个孩子,其中 m/2 <= k <= m。
三、每个叶子节点都包含 k - 1 个元素,其中 m/2 <= k <= m。
四、全部的叶子节点都位于同一侧。
五、每一个节点中的元素从小到大排列,节点当中的 k - 1 个元素正好是 k 个孩子包含的元素的值域划分。
小秋:我去,这么复杂,鬼才记得住,我仍是选择不学了,呜呜。
帅地:你别着急,这些规则我也记不住,只是让你大体知道一些这些规则,通常状况下,咱们并不须要把它的规则彻底背起来滴。为了加深理解,我给你举个 B 树的例子吧。例如:
图中是一棵m = 3 的 3 阶 B 树,能够看出,树中有些节点是有多个元素的,而且和二叉查找树同样,左节点的全部元素的值都比父亲元素小。例如对于(3, 7)这个节点。两个元素把这个节点分割成三个值域,便可以有 3 个孩子。2 至关于 3 的左孩子节点,而 (4,6)至关于 3 的右孩子,同时也是 7 的左孩子,而 9 是 7 的右孩子。
和二叉查找树仍是很类似滴,都是有序,且左孩子小,右孩子大,只是 B 树的一个节点能够有多个元素,而且有多个分支。而这些分支以及元素的数量规则,能够从上面的五个规则中查找哈。说实话,我也懒的记那些规则,只知道个大概以及 B 树的应用便可。
文章来源于微信公众:『苦逼的码农』,更多文章可搜索关注
小秋:我知道了,不过这种多叉的树,真的能够比二叉查找树效率更好吗,我怎么以为不能够呢?
帅地:那你能够说说哦。
小秋:例如,上面的 B 树有 11 个元素,按照这 11 个元素,咱们创建一个以下的二叉查找树,如图(我去,这个图话了好长时间,ppt 画的)
下面咱们来进行查询效率比较
一、在 B 树中的查找次数。 如今假如咱们要查询元素 9,对于 B 树,咱们须要进行4次比较,例如: 第一次比较: 10 比较,比 10 小,因此再 10 的左孩子找。
第2、三次比较:和 3 比较,比 3 大,这个时候咱们还得和 7 比较。
第四次比较:和 9 比较,相等,找到目标树,返回。
因此最终的结果须要 4 次比较。
二、在二叉树的比较结果
为了节省篇幅,我就不逐个比较了,相信你也一眼就看出来了,也是须要 4 次比较。如图
小秋:一样都是四次比较,并且,B 树的每个节点,若是存放的元素比较多,那么 B 树的比较次数会更多,为何就说 B 的效率比 二叉查找树快呢?
帅地:确实,若是单单从比较次数看的话,二叉查找树确实不比 B 树差,不过你忽略了一个很重要的点,那就是磁盘的寻址加载次数。
咱们知道,在把磁盘里的数据加载到内存中的时候,是以页为单位来加载的,而咱们也知道,节点与节点之间的数据是不连续的,因此不一样的节点,颇有可能分布在不一样的磁盘页中。因此对于上面的二叉查找树,咱们可能须要进行 4 次寻址加载,如图:
而对于 B 树,因为 B 树的每个节点,能够存放多个元素,因此磁盘寻址加载的次数会比较少,例如上面的例子中,用 B 树的话,只须要加载 3 次,如图:
咱们都知道,在内存的运算速度是很是快的,至少比磁盘的寻址加载速度,快了几百倍,而咱们进行数值比较的时候,是在内存中进行的,虽然 B 树的比较次数可能比二叉查找树多,可是磁盘操做次数少,因此整体来讲,仍是 B 树快的多,这也是为何咱们用使用 B 树来存储的缘由。
小秋:原来这样啊,之前一直蒙在鼓里。
文章来源于微信公众:『苦逼的码农』,更多文章可搜索关注
帅地:不知道你发现没有,实际上磁盘的加载次数,基本上是和树的高度相关联的,高度越高,加载次数越多,越矮,加载次数越少。因此对于这种文件索引的存储,咱们通常会选择矮胖的树形结构。例若有 1000 个元素,若是是二叉查找树的话,高度可能高达 10 层,而若是用 10 阶 B 树的话,只须要三四层便可。
小秋:终于搞懂了,不过我还有个疑问,大部分文件索引或者数据库索引都是用 B+ 树的,而只有小部分才用 B 树,能够问下为什要用 B+ 树而不用 B 树吗?还有,B 树还有其余的应用吗?
帅地:B 树处于会用在少部分的文件索引(数据库索引)外,应用的最多的就是文件系统了。至于为什呀要用 B 树而不用 B+ 树,为何数据库索引大部分用 B+ 树而不用 B 树,咱们下节再讲了。
小秋:那我期待着。
帅地:若是以为有收获,能够帮忙多多转发,点赞,分享哦,这也是我写文章的动力来源。
关于 B 树和 B+ 树,在面试的过程当中,仍是问的挺多滴,特别是问到数据库的时候,基本会问索引,进而问到 B+ 树,从而也会扯到 B 树。因此掌握着两种树的应用以及原理,是很是重要的,虽然他们的规则很复杂,可是若是是应付面试等,其实不须要背那些规则,只须要知道大概以及知道他们的原理便可。
若是你以为这篇内容对你挺有启发,我想邀请你帮我三个忙,让更多的人看到这篇文章:
一、点赞,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓 -_-)
二、关注我和专栏,让咱们成为长期关系
三、关注公众号「苦逼的码农」,主要写算法、计算机基础之类的文章,里面已有100多篇原创文章