一 B树

1.B树的定义:B树(B-tree)是一种树状数据结构,它能够存储数据、对其进行排序并允许以O(log n)的时间复杂度运行进行查找、顺序读取、插入和删除的数据结构。B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树。

2.B树的特征:

  • 根节点至少有两个子节点
  • 每个中间节点都包含k-1个元素和k个孩子,其中 m/2 ≤ k ≤ m (m为树的阶)
  • 每个叶子节点都包含k-1个元素,其中 m/2 ≤ k ≤ m (m为树的阶)
  • 每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域划分(一个结点有k个孩子时,必有k-1个元素才能将子树中所有元素划分为k个子集)

3.B树的操作

3.1 B树的查找:如下图,查询元素8

第一次磁盘IO:把15所在节点读到内存中,然后与8做比较,小于15,找到下一个节点(5和9对应的节点)

第二次磁盘IO:把5和9所在的节点读到内存中,然后与8做比较,5<8<9,找到下一个节点(6和8对应的节点)

第三次磁盘IO:把6和8所在节点读到内存中,然后与8做比较,找到了元素8

3.1 B树的插入: 将元素7插入下图中的B树

步骤一:自顶向下查找元素7应该在的位置,即在6和8之间

步骤二:三阶B树中的节点最多有两个元素,把6 7 8里面的中间元素上移(中间元素上移是插入操作的关键)

步骤三:上移之后,上一层节点元素也超载了,5 7 9中间元素上移,现在根节点变为了 7 15

步骤四:要对B树进行调整,使其满足B树的特性,最终如下图:

二 B+树 

B+树是B树的一种变形体,它与B树的差异在于:

  • 有K个子节点的节点必然有K个关键码
  • 非叶节点仅具有索引作用,元素信息均存放在叶节点中
  • 树的所有叶节点构成一个有序链表,可以按照关键码排序的次序遍历全部记录

B+树的优势:

  • 由于B+树在内部节点上不包含数据信息,因此在内存页中能够存放更多的key。 数据存放的更加紧密,具有更好的空间局部性。因此访问叶子节点上关联的数据也具有更好的缓存命中率。
  • B+树的叶子节点都是相连的,因此对整棵树的遍历只需要一次线性遍历叶子节点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。

总结:我们知道二叉查找树的时间复杂度是O(logN),效率已经足够高。为什么出现B树和B+树呢?当大量数据存储在磁盘上,进行查询操作时,需要先将数据加载到内存中(磁盘IO操作),而数据并不能一次性全部加载到内存中,只能逐一加载每个磁盘页(对应树的一个节点),并且磁盘IO操作很慢,平衡二叉树由于树深度过大而造成磁盘IO读写过于频繁,进而导致效率低下。为了减少磁盘IO的次数,就需要降低树的深度,那么就引出了B树和B+树:每个节点存储多个元素,采用多叉树结构。这样就提高了效率,比如数据库索引,就是存储在磁盘上,采用的就是B+树的数据结构。

B树和B+树详解的更多相关文章

  1. 哈夫曼树(三)之 Java详解

    前面分别通过C和C++实现了哈夫曼树,本章给出哈夫曼树的java版本. 目录 1. 哈夫曼树的介绍 2. 哈夫曼树的图文解析 3. 哈夫曼树的基本操作 4. 哈夫曼树的完整源码 转载请注明出处:htt ...

  2. 哈夫曼树(二)之 C++详解

    上一章介绍了哈夫曼树的基本概念,并通过C语言实现了哈夫曼树.本章是哈夫曼树的C++实现. 目录 1. 哈夫曼树的介绍 2. 哈夫曼树的图文解析 3. 哈夫曼树的基本操作 4. 哈夫曼树的完整源码 转载 ...

  3. B树、B+树、B*树三者的对比详解

    转载至:https://www.2cto.com/database/201805/745822.html 对比 B+树是B树的变体,B*树又是B+树的变体,是一脉相承法治国拉的,不断解决新一阶段的问题 ...

  4. AVL树的旋转操作详解

    [0]README 0.0) 本文部分idea 转自:http://blog.csdn.net/collonn/article/details/20128205 0.1) 本文仅针对性地分析AVL树的 ...

  5. 有趣的 zkw 线段树(超全详解)

    zkw segment-tree 真是太棒了(真的重口味)!写篇博客纪念入门 emmm...首先我们来介绍一下 zkw 线段树这个东西(俗称 "重口味" ,与 KMP 类似,咳咳. ...

  6. BZOJ 1912: [Apio2010]patrol 巡逻 (树的直径)(详解)

    题目: https://www.lydsy.com/JudgeOnline/problem.php?id=1912 题解: 首先,显然当不加边的时候,遍历一棵树每条边都要经过两次.那么现在考虑k==1 ...

  7. 可持久化线段树(主席树)(图文并茂详解)【poj2104】【区间第k大】

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=63740442 向大(hei)佬(e)实力学(di ...

  8. AVL树(二叉平衡树)详解与实现

    AVL树概念 前面学习二叉查找树和二叉树的各种遍历,但是其查找效率不稳定(斜树),而二叉平衡树的用途更多.查找相比稳定很多.(欢迎关注数据结构专栏) AVL树是带有平衡条件的二叉查找树.这个平衡条件必 ...

  9. 决策树--CART树详解

    1.CART简介 CART是一棵二叉树,每一次分裂会产生两个子节点.CART树分为分类树和回归树. 分类树主要针对目标标量为分类变量,比如预测一个动物是否是哺乳动物. 回归树针对目标变量为连续值的情况 ...

  10. 从Trie树(字典树)谈到后缀树

    转:http://blog.csdn.net/v_july_v/article/details/6897097 引言 常关注本blog的读者朋友想必看过此篇文章:从B树.B+树.B*树谈到R 树,这次 ...

随机推荐

  1. 架构师入门:Spring Cloud系列,Hystrix与Eureka的整合

    和Ribbon等组件一样,在项目中,Hystrix一般不会单独出现,而是会和Eureka等组件配套出现.在Hystrix和Eureka整合后的框架里,一般会用到Hystrix的断路器以及合并请求等特性 ...

  2. springboot项目容器化

    创建一个简单的springboot项目,依赖中加入: 编写一个Restfull接口: 编写启动类: 启动项目,浏览器访问该接口,得到想要的结果.下面,就将这个项目进行Docker容器化(applica ...

  3. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2版本正式发布

     RDIFramework.NET .NET快速信息化系统开发框架 V3.2版本 正式发布 精益求精求完美! 1.RDIFramework.NET框架介绍 RDIFramework.NET,基于.NE ...

  4. Java内存模型JMM 高并发原子性可见性有序性简介 多线程中篇(十)

    JVM运行时内存结构回顾 在JVM相关的介绍中,有说到JAVA运行时的内存结构,简单回顾下 整体结构如下图所示,大致分为五大块 而对于方法区中的数据,是属于所有线程共享的数据结构 而对于虚拟机栈中数据 ...

  5. AspNetCore 基于AOP实现Polly的使用

    前言   说起AOP,其实我们在做MVC/API 的时候应该没少接触,比如说各种的Fitter 就是典型的AOP了. 本来在使用Polly的时候我最初的打算是使用过滤器来实现的,后来发现实现起来相当的 ...

  6. 折腾Java设计模式之迭代器模式

    迭代器模式 Provide a way to access the elements of an aggregate object sequentially without exposing its ...

  7. Vue.js实现登录功能

    编写html,通过vue-resource.js库向后台提交数据 <!DOCTYPE html> <html lang="en"> <head> ...

  8. Math.floor(Math.random()*3+1)

    Math.random():获取0~1随机数 Math.floor() method rounds a number DOWNWARDS to the nearest integer, and ret ...

  9. 章节十、8-XPath---如何构建有效的XPath

    以下演示操作以该网址中的内容为例:https://learn.letskodeit.com/?_ga=2.143454972.85111248.1555037144-697706367.1554889 ...

  10. Vue.js02:数据绑定v-model用法

    <!-- v-model 实现数据的双向绑定 --> <!-- v-model 只能用在表单元素中 --> 示例: <!DOCTYPE html> <!-- ...