面试官问你B树和B+树,就把这篇文章丢给他

  1 B树
  
  在介绍B+树之前, 先简单的介绍一下B树,这两种数据结构既有相似之处,也有他们的区别,最后,我们也会对比一下这两种数据结构的区别。
  
  1.1 B树概念
  
  B树也称B-树,它是一颗多路平衡查找树。二叉树我想大家都不陌生,其实,B树和后面讲到的B+树也是从最简单的二叉树变换而来的,并没有什么神秘的地方,下面我们来看看B树的定义。
  
  每个节点最多有m-1个关键字(可以存有的键值对)。
  
  根节点最少可以只有1个关键字。
  
  非根节点至少有m/2个关键字。
  
  每个节点中的关键字都按照从小到大的顺序排列,每个关键字的左子树中的所有关键字都小于它,而右子树中的所有关键字都大于它。
  
  所有叶子节点都位于同一层,或者说根节点到每个叶子节点的长度都相同。
  
  每个节点都存有索引和数据,也就是对应的key和value。
  
  所以,根节点的关键字数量范围:1 <= k <= m-1,非根节点的关键字数量范围:m/2 <= k <= m-1。
  
  另外,我们需要注意一个概念,描述一颗B树时需要指定它的阶数,阶数表示了一个节点最多有多少个孩子节点,一般用字母m表示阶数。
  
  我们再举个例子来说明一下上面的概念,比如这里有一个5阶的B树,根节点数量范围:1 <= k <= 4,非根节点数量范围:2 <= k <= 4。
  
  下面,我们通过一个插入的例子,讲解一下B树的插入过程,接着,再讲解一下删除关键字的过程。
  
  1.2 B树插入
  
  插入的时候,我们需要记住一个规则:判断当前结点key的个数是否小于等于m-1,如果满足,直接插入即可,如果不满足,将节点的中间的key将这个节点分为左右两部分,中间的节点放到父节点中即可。
  
  例子:在5阶B树中,结点最多有4个key,最少有2个key(注意:下面的节点统一用一个节点表示key和value)。
  
  插入18,70,50,40
  
  插入22
  
  插入22时,发现这个节点的关键字已经大于4了,所以需要进行分裂,分裂的规则在上面已经讲了,分裂之后,如下。
  
  接着插入23,25,39
  
  分裂,得到下面的。
  
  更过的插入的过程就不多介绍了,相信有这个例子你已经知道怎么进行插入操作了。
  
  1.3 B树的删除操作
  
  B树的删除操作相对于插入操作是相对复杂一些的,但是,你知道记住几种情况,一样可以很轻松的掌握的。
  
  现在有一个初始状态是下面这样的B树,然后进行删除操作。
  
  删除15,这种情况是删除叶子节点的元素,如果删除之后,节点数还是大于m/2,这种情况只要直接删除即可。
  
  接着,我们把22删除,这种情况的规则:22是非叶子节点,对于非叶子节点的删除,我们需要用后继key(元素)覆盖要删除的key,然后在后继key所在的子支中删除该后继key。对于删除22,需要将后继元素24移到被删除的22所在的节点。
  
  此时发现26所在的节点只有一个元素,小于2个(m/2),这个节点不符合要求,这时候的规则(向兄弟节点借元素):如果删除叶子节点,如果删除元素后元素个数少于(m/2),并且它的兄弟节点的元素大于(m/2),也就是说兄弟节点的元素比最少值m/2还多,将先将父节点的元素移到该节点,然后将兄弟节点的元素再移动到父节点。这样就满足要求了。
  
  我们看看操作过程就更加明白了。
  
  接着删除28,删除叶子节点,删除后不满足要求,所以,我们需要考虑向兄弟节点借元素,但是,兄弟节点也没有多的节点(2个),借不了,怎么办呢?如果遇到这种情况,首先,还是将先将父节点的元素移到该节点,然后,将当前节点及它的兄弟节点中的key合并,形成一个新的节点。
  
  移动之后,跟兄弟节点合并。
  
  删除就只有上面的几种情况,根据不同的情况进行删除即可。
  
  上面的这些介绍,相信对于B树已经有一定的了解了,接下来的一部分,我们接着讲解B+树,我相信加上B+树的对比,就更加清晰明了了。
  
  2 B+树
  
  2.1 B+树概述
  
  B+树其实和B树是非常相似的,我们首先看看相同点。
  
  根节点至少一个元素
  
  非根节点元素范围:m/2 <= k <= m-1
  
  import numpy as np
  
  import numpy.fft as nf
  
  import scipy.io.wavfile as wf
  
  import matplotlib.pyplot as plt
  
  # 读取音频文件
  
  sample_rate, noised_sigs = wf.read(www.shengsyLpt.cn‘./da_data/noised.wav‘)
  
  print(sample_rate)www.yuntianyul.com # sample_rate:采样率44100
  
  print(noised_sigs.shape) www.myzx1.com www.xinchenptgw.cn # noised_sigs:存储音频中每个采样点的采样位移(220500,)
  
  times = np.arange(noised_sigs.size) / sample_rate
  
  plt.figure(‘Filter‘www.zhongxinyul2.com)
  
  plt.subplot(221)
  
  plt.title(‘Time Domain‘, fontsize=16)
  
  plt.ylabel(‘Signal‘, fontsize=12)
  
  plt.tick_params(labelsize=10)
  
  plt.grid(linestyle=‘:‘)
  
  plt.plot(times[:178], noised_sigs[:178], c=www.jinyazptdL.cn‘orangered‘, label=‘Noised‘)
  
  plt.legend(www.jintianxuesha.com)
  
  B+树有两种类型的节点:内部结点(也称索引结点)和叶子结点。内部节点就是非叶子节点,内部节点不存储数据,只存储索引,数据都存储在叶子节点。
  
  内部结点中的key都按照从小到大的顺序排列,对于内部结点中的一个key,左树中的所有key都小于它,右子树中的key都大于等于它。叶子结点中的记录也按照key的大小排列。
  
  每个叶子结点都存有相邻叶子结点的指针,叶子结点本身依关键字的大小自小而大顺序链接。
  
  父节点存有右孩子的第一个元素的索引。
  
  下面我们看一个B+树的例子,感受感受它吧!
  
  2.2 插入操作
  
  对于插入操作很简单,只需要记住一个技巧即可:当节点元素数量大于m-1的时候,按中间元素分裂成左右两部分,中间元素分裂到父节点当做索引存储,但是,本身中间元素还是分裂右边这一部分的。
  
  下面以一颗5阶B+树的插入过程为例,5阶B+树的节点最少2个元素,最多4个元素。
  
  插入5,10,15,20
  
  插入25,此时元素数量大于4个了,分裂
  
  接着插入26,30,继续分裂
  
  有了这几个例子,相信插入操作没什么问题了,下面接着看看删除操作。
  
  2.3 删除操作
  
  对于删除操作是比B树简单一些的,因为叶子节点有指针的存在,向兄弟节点借元素时,不需要通过父节点了,而是可以直接通过兄弟节移动即可(前提是兄弟节点的元素大于m/2),然后更新父节点的索引;如果兄弟节点的元素不大于m/2(兄弟节点也没有多余的元素),则将当前节点和兄弟节点合并,并且删除父节点中的key,下面我们看看具体的实例。
  
  初始状态
  
  删除10,删除后,不满足要求,发现左边兄弟节点有多余的元素,所以去借元素,最后,修改父节点索引
  
  删除元素5,发现不满足要求,并且发现左右兄弟节点都没有多余的元素,所以,可以选择和兄弟节点合并,最后修改父节点索引
  
  发现父节点索引也不满足条件,所以,需要做跟上面一步一样的操作
  
  这样,B+树的删除操作也就完成了,是不是看完之后,觉得非常简单!
  
  3 B树和B+树总结
  
  B+树相对于B树有一些自己的优势,可以归结为下面几点。
  
  单一节点存储的元素更多,使得查询的IO次数更少,所以也就使得它更适合做为数据库MySQL的底层数据结构了。
  
  所有的查询都要查找到叶子节点,查询性能是稳定的,而B树,每个节点都可以查找到数据,所以不稳定。
  
  所有的叶子节点形成了一个有序链表,更加便于查找。

原文地址:https://www.cnblogs.com/qwangxiao/p/11559255.html

时间: 2024-10-09 06:16:24

面试官问你B树和B+树,就把这篇文章丢给他的相关文章

面试官问:如何让其他部门重视数据?该怎么答?

本文转自知乎 作者:接地气的陈老师 ----------------------------------------------------- 有同学问:老师,面试官问了我一个这样的问题:"管销售的领导一直不关心数据,而且人家那个部门也一直业绩排名第一,每年的指标都能达标,要怎样让这个领导重视起来呢?"我该怎么回答???? 答:如果不是面试的话,我建议直接放弃这哥们吧.回顾一下我们讲过的业务部门分类(如下图) 天天做用户画像,有多少同学对企业内部数据分析部门的用户进行过画像?哈哈 业务

面试官问现在工资是多少,该怎么回答?

面试,是一个推销自己的过程,先谈能力,后聊价格,顺序不能乱.如何谈薪资,能够做到对候选人最有利,是一门学问,也需要大量的实践.今天,我介绍两个谈薪资的要点给大家,稍加练习,便足以应对大部分的场面. 这个世界,从来都不是公平和客观的,面试也一样.用人单位对候选人的定价,从不看真实价值,往往只根据候选人当前的薪资来定,并且默认最多只会增幅0-20%(没错,不少公司在某些情况下一分钱都不会涨),而候选人对跳槽涨薪的预期一般是30%起.天然的,在谈判开始前,双方对薪资涨幅的预期,就存在巨大鸿沟,如何跨越

面试官问我,使用Dubbo有没有遇到一些坑?我笑了。

前言 17年的时候,因为一时冲动没把持住(当然最近也有粉丝叫我再冲动一把再更新一波),结合面试题写了一个系列的Dubbo源码解析.目前公众号大部分粉丝都是之前的粉丝,这里不过多介绍. 面试官问我,使用Dubbo有没有遇到一些坑?我笑了.根据我的面试经验而言,能在简历上写上原理.源码等关键词的,是非常具备核心竞争力的.上周和一个公众号粉丝交流面试情况如下 面试官问我,使用Dubbo有没有遇到一些坑?我笑了.面试的时候,把源码一波分析,令面试官虎躯一震!在一阵前戏过后,以为接下来无非就是身体的一顿抽

大厂面试官问你META-INF/spring.factories要怎么实现自动扫描、自动装配?

大厂面试官问你META-INF/spring.factories要怎么实现自动扫描.自动装配? 很多程序员想面试进互联网大厂,但是也有很多人不知道进入大厂需要具备哪些条件,以及面试官会问哪些问题,这里今天就给大家分享一下,如果大厂面试官问你META-INF/spring.factories要怎么实现自动扫描.自动装配,你需要怎么回答? 程序员应聘面试经验技巧和注意事项你知道哪些? 1.基础很重要,不要生疏了. 2.要关注技术前沿. 3.小公司比较看重知识的广度,大公司更看重知识的深度. 4.良好

【转载】如果有人问你数据库的原理,叫他看这篇文章

原文:如果有人问你数据库的原理,叫他看这篇文章 本文由 伯乐在线 - Panblack 翻译,黄利民 校稿.未经许可,禁止转载!英文出处:Christophe Kalenzaga.欢迎加入翻译组. 一提到关系型数据库,我禁不住想:有些东西被忽视了.关系型数据库无处不在,而且种类繁多,从小巧实用的 SQLite 到强大的 Teradata .但很少有文章讲解数据库是如何工作的.你可以自己谷歌/百度一下『关系型数据库原理』,看看结果多么的稀少[译者注:百度为您找到相关结果约1,850,000个…] 

[ZZ]如果有人问你数据库的原理,叫他看这篇文章

如果有人问你数据库的原理,叫他看这篇文章 http://blog.jobbole.com/100349/ 文章把知识链都给串起来,对数据库做一个概述. 合并排序 阵列.树和哈希表 B+树索引概述 数据库的全局概述 基于成本的优化概述,特别专注了联接运算 缓冲池管理概述 事务管理概述

去百度面试,想知道面试官问哪些问题,看这篇文章

https://mp.weixin.qq.com/s?__biz=MzI0NjM3NjI1NQ==&mid=2247487861&idx=1&sn=34316976cdb0aa2e4df3aa6f1f5cc31d&chksm=e9416325de36ea33200d9944fff37381de11c8d4dc8aeb0cc4b83c6201e56b8ee2bc8c2798cc&mpshare=1&scene=1&srcid=1102ElP5k7MBT

当面试官问你:如何进行性能优化?

问题背景 在开发好页面后,如何让页面更快更好的运行,是区分一个程序猿技术水平和视野的一个重要指标.所以面试时,面试官总会问你一个问题,如何进行性能优化呢? 性能优化是什么 从前端的角度来说,性能优化可以分为两个方向.从用户角度来看,一个是页面加载的很快,另一个是页面使用起来很流畅.因此,对性能优化的探索,我们可以分为页面加载时间跟页面运行效率两个方向来进行研究 从浏览器打开到页面渲染完成,花费了多少时间 浏览器解析->查询缓存->dns查询->建立链接->服务器处理请求->服

大厂面试官问你知道final、finally、finalize有什么区别?

前言Java程序员面试,基础真的很重要.基础这东西,各个公司都很看重,尤其是大公司,他们看中人的潜力,他们舍得花精力去培养,所以基础是重中之重.之前很多人问我,项目经历少怎么办,那就去打牢基础,当你的基础好的发指的时候,你的其他东西都不重要了. Java 语言有很多看起来很相似,但是用途却完全不同的语言要素,这些内容往往容易成为面试官考察你知识掌握程度的切入点.今天,我要问你的是一个经典的 Java 基础题目,谈谈 final.finally. finalize 有什么不同?典型回答final