一 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. TypeScript 中非代码模块的导入

    需要理解的是,TypeScript 作为语言,他只处理代码模块.其他类型的文件这种非代码模块的导入,讲道理是通过另外的打包工具来完成的,比如 Web 应用中的图片,样式,JSON 还有 HTML 模板 ...

  2. 新建项目到Jenkins中

    在以Jenkins为镜像创建Docker容器时,我们在jenkins的dockerfile文件中写明了要安装Docker Compose,目的也是在Jenkins容器中借助Docker Compose ...

  3. C#代码安装Windows服务(控制台应用集成Windows服务)

    最近在为一款C/S架构的科研软件开发云计算版,需要用到WCF,考虑到不需要什么界面以及稳定性,无人值守性,准备用Windows Service作为宿主,无奈Windows Service的安装太为繁复 ...

  4. PyCharm出现TabError: inconsistent use of tabs and spaces in indentation最简单实用的解决办法

    本文使用PyCharm的格式化代码功能解决TabError: inconsistent use of tabs and spaces in indentation. 当把代码从别处复制进来PyChar ...

  5. mysql_8.0.12环境配置

    1. 官网下载mysql_8.0.12免安装包,解压到你存放的地方: 2. 配置环境变量(把bin的文件夹弄进系统path里面): 3. 在解压的根路径中,查看是否含有my.ini文件,没有就新建一个 ...

  6. 10分钟 在linux里创建.net core helloworld控制台程序

    官方教程 安装linux https://www.cnblogs.com/LittleFeiHu/p/9749455.html 第一步 :选择和你本机适用的Linux版本,我这里用的是18.04. 第 ...

  7. DevExpress AspxGridView分页使用隐藏系统默认英文分页

    1第一篇文章研究了怎么汉化,但是在实际使用过程中发现汉化的有小问题,DevExpress支持自定义按钮,也可以在属性中设置成中文,这样避免汉化不准确的问题 <dx:ASPxGridView ID ...

  8. Java开发笔记(八十三)利用注解技术检查空指针

    注解属于比较高级的Java开发技术,前面介绍的内置注解专用于编译器检查代码,另外一些注解则由各大框架定义与调用,像Web开发常见的Spring框架.Mybatis框架,Android开发常见的Butt ...

  9. es6 字符串的扩展和数值的扩展

    es6字符串的扩展 1. es6新增的一些方法 1.1 includes 判断是否包括在内,返回一个 true or false 1.2 statsWith 判断是否以什么开头,返回一个 true o ...

  10. 二分查找BinarySearch(Java)

    二分查找(折半查找)BinarySearch 二分查找  一组排好顺序的数,查找其中的一个数(value)的位置,按照数组(int[] a)存放这组数据,数组的索引所指的位置就是需要查找的数,用三个变 ...