B树

  • 前几篇文中讨论的数据结构我们都是假设所有的数据都存储在计算机的主存中。可说总要那么海量的数据需要通过个中数据结构去存储,我们不可能有这么多内存区存放这些数据。那么意味着我们需要将他们放磁盘。所以这个时候范问时间复杂度O决定了他是否能适合存储磁盘,大O模型不适用于磁盘存储。游戏规则变了。

  • 在磁盘中操作速度和CPU内存计算速度相差甚远。

    • 例如一台机器每秒可以执行5亿条指令。
    • 磁盘读写操作依赖磁盘的机械运动,磁盘转动,磁针移动,也许磁盘7200RPM的转速,1转大约1/120秒,约8.3ms,我们就估算是8.3
    • 每秒大概120次磁盘访问
    • 但是1分钟7200转比起每秒5亿简直不是一个量级,比值相当于 40W:1
    • 方法是尽量减少磁盘的操作,宁愿大量计算
    • 对于树来说,一个节点存在几个子节点,我们在内存中通过指针寻址,但是在磁盘中需要机械运动寻址
案例
  • 我们通过一个案例来结束典型查找树的执行方式:

    • 假设要访问广东市所有人的出行记录。假设只有1kw项数据。每个关键字32字节(是这个人的名字+唯一id),而一个记录存储这N个信息是256个字节。假设这些1kw数据不能都存储进主内存
    • 更具如上计算,我们
解决方法
  • 不平衡的二叉查找树解决如上问题完全不可取,最坏情况他有线性深度,从而可能需要1kw次磁盘的范问。平均的话一次成功的查找也需要1.38logN次范围,由于log10000000 =24 ,1.38*24 = 32/6 = 5秒。AVL树多少要好一点,1.44logN是最坏情况,平均访问是logN,择优AVL计算平均25次磁盘查询一个数据,4秒左右

  • 要减少磁盘范问次数,比如减到3,4。我们需要更加复杂的程序。因为机器指令相对机械操作相当于不耗时。以上分析我们知道二叉树不可行,减少树层级增加节点分支的方式来解决。

  • 31个节点的完美二叉树有5层,31个节点的5叉树只有3层

  • 一个完全二叉树的高度大概是log2N,而一颗完全M叉树的高度大概是LogMN

  • 我们建立与二叉树类似的M叉查找树,二叉树中我们需要一个key来决定走左树还是右树,M叉树我们需要M-1个key来决定

  • 同时避免M叉树退化成链表,我们需要给一个平衡条件,限制M叉树退化到二叉树,那就是B树如下性质

  • 阶为M的B树是一颗具有下列特性的树:

    • 数据项存储在叶子节点上
    • 非叶子节点存储直到M-1个关键字用来指示搜索方向;关键字i代表子树i+1中最小关键字
    • 数的根节点如果不是叶子节点,那么他子节点个数必须在2~M之间
    • 除了根节点外,所有非叶子节点的子节点个数必须在M/2~M个之间
    • 所有叶子节点都在相同的深度上,并且有L/2和L个数据项目,L个数之后确认
  • 如下图5阶B树的案例,所有非叶子节点的儿子树都在3~5之间(5/2 ~ 5 取整 3-5),那么他们有2-4个关键字;根可能只有2个子节点。这里我们L=5,所有叶子节点的数据项则是(5/2 ~5 取整 3-5 之间)

    • 要求节点半满保证B树不退化到简单二叉树
B树结构分析
  • 我们根据所存储的项的大小选择M与L的大小,还是上面的案例,我们假设一个区块的磁盘大小是8192Byte,
  • 每个关键字32Byte,在一颗M阶B数中,有M-1个关键字那么总数是32(M-1),再加上M个分支(指针int型4Byte),总数则为32(M-1)+4M = 36M-32
  • 那么一个片区8192可以存储的最大节点数据是8192= (36M-32) , M = 228阶,也就是我们每一层有228个分支
  • 以上案例中条件说一个记录256Byte,8192/256 = 32 ,一个片区可以存储32个记录,我们选择L=32,这样一个子节点中所有数据可以在同一个片区(尽量一次磁盘操作可以读完)
  • 这样我们保证了每个叶子节点有16~32个数据记录以及每个内部节点至少有228/2 = 114 中分支方式
  • 那么1kw个数据最多存储的叶子节点个数 10000000/16 = 625000 个叶子节点中
  • 层级最少情况,每一层都是满分支(228),625000/228 = 224 /228 = 1,最少的情况第二次就是叶子节点
  • 层级最多情况,每一层都是半分支(228/2=114),625000/114 = 5482.4/114=48/1154 = 1 ,最多情况第四层是叶子节点
  • 如上分析,最坏情况访问次数近似log(m/2)N给出
构造B树–添加节点,删除节点
插入节点
  • 我们按照上面图片中的案例,需要将57 插入到图中的B树,沿着树向下查找他不在树中,我们把它作为第五项数据添加到第对应的叶子节点中如下图:
方法一
  • 如上更新数据分为三步:

    • 第一遍历B树,找到插入数据的对应位置
    • 读取树叶节点中数据并且重排树叶节点中数据
    • 将重排的数据写入树叶节点
  • 与磁盘的操作相比,这些逻辑排列时间几乎可以忽略不计,以上是简单的模式,因为改树叶节点并没有被装满,现在我们在插入55 到上图中。
    • 55要插入的那个叶子节点已经满,有L+1项数据,我们需要将他分成两个叶子节点,这两叶子节点能保证所有需要的记录的最小个数,每一个叶子节点3个项(需要两次磁盘范问)
    • 接着我们需要更新父节点,将最小的值添加到父节点中(需要一次写入的磁盘操作),这种方式是更具上面L/2的规则执行
    • 虽然分离节点是耗时的,至少需要2次磁盘操作,但是很少发生,比如我们上面L=32 时候每次节点分裂时候都有16 或者17 项数据的两片叶子节点,那么我们需要之后的17次添加操作才会有一次分裂

  • 如上图情况,当一个非叶子节点分裂,父节点得到一个新的子节点,父节点也需要增加一个项,如果父节点此时也达到分裂阀值,则需要继续向上分裂直到达到根节点。如果分裂根就得到两个根,这显然不现实,我们则创建一个新根,这个根以分裂得到的两个新根为子节点,所以我们的根节点的子节点的个数设置在2~M个是有这个原因的。
  • 这种方式也是B树增加高度的唯一方式
方法二
  • 在相邻节点有空间时候,将一个子节点交给邻节点,例如将上图中29 节点插入到B树中,我们可以把32移到 下一片树叶而腾出一个空间来,这种方法要求对父节点进行修改,因为这些关键字也会受影响,他趋向于是的节点达到满节点,更加节省空间。
删除节点
  • 通过查找到要删除的项并在找到后删除他来执行删除操作,问题在于,如果被删元素的总元素个数已经低于最小值(L/2),那么删除后他的项目就不符合B树的要求,我们可以通过在邻节点借一个节点来矫正这种情况,如果邻节点也达到最小值(L/2),那么我们就合并这两个叶子节点结合成一个新的满叶节点。
  • 这种操作意味着父节点是去一个儿子,如果失去儿子节点后又引发儿子节点数低于下限,我们继续使用相同的策略,一直到根节点,如果这个过程使得根只剩下一个子节点,那么删除这个根节点,让原儿子节点当现在B树的新根节点。
  • 这种方式是B树降低高度的唯一方式。
  • 如下案例,我们还是依照上图中的B数,删除99 项的节点,由于叶子节点只有两个,而其邻节点以及是最小值3 个了,因此,我们将这两个叶子节点合并成有5项数据的一片新的叶子节点。结果他的父节点只有两个子节点,此时父节点继续上一个步骤,从邻节点领养,邻节点有4个子节点,最终使用双方都得到3个子节点,如下图:

上一篇:数据结构与算法–AVL树原理及实现
下一篇:数据结构与算法–图论,最短路算法,拓扑排序算法

数据结构与算法--B树原理及实现相关推荐

  1. 数据结构与算法--二叉查找树实现原理

    二叉查找树 二叉树的一个重要应用就是他在查询中的使用,假设书中每个节点存储一项数据.在我们的案例中,任意复杂的项在java中都容易处理,但为了简单还是假设都是整数.还假设他们都是不重复的整数,使二叉树 ...

  2. 数据结构与算法——AVL树类的C++实现

    关于AVL树的简单介绍能够參考: 数据结构与算法--AVL树简单介绍 关于二叉搜索树(也称为二叉查找树)能够參考:数据结构与算法--二叉查找树类的C++实现 AVL-tree是一个"加上了额 ...

  3. 《数据结构与算法》——树与二叉树之遍历总结

    <数据结构与算法>--树与二叉树之遍历总结 树与二叉树部分计划分为三次进行复习总结,第一次为基本概念和二叉树的遍历,第二次内容为线索二叉树以及树和森林,第三次为树与二叉树的应用. 目录 & ...

  4. 高级数据结构与算法 | AVL树 (高度平衡树)

    文章目录 AVL树 实现思路 数据结构 查找 平衡因子 旋转 右旋 左旋 右左双旋 左右双旋 插入 删除 AVL树的验证 中序遍历 平衡判断 AVL树的性能 完整代码实现 AVL树 AVL树是最先发明 ...

  5. 数据结构与算法(3)——树(二叉、二叉搜索树)

    前言:题图无关,现在开始来学习学习树相关的知识 前序文章: 数据结构与算法(1)--数组与链表(https://www.jianshu.com/p/7b93b3570875) 数据结构与算法(2)-- ...

  6. 数据结构与算法:树与二叉树python实现

    最近复习一遍数据结构与算法,做一些笔记,大家可以一起复习. 一.树的一些容易混淆的定义: 结点层:根结点的层定义为1:根的孩子为第二层结点,依此类推: 树的深度(或高度):树中最大的结点层: 满二叉树 ...

  7. 数据结构与算法--二叉树实现原理

    二叉树 二叉树(binary tree)是一棵树,其中每个节点都不能有多于两个的子节点 二叉树的一个性质是一颗平均二叉树的深度要比节点个数N小得多(重点),对二叉树的分析得出其平均深度为O(N\sqr ...

  8. 数据结构和算法——kd树

    一.K-近邻算法 K-近邻算法是一种典型的无参监督学习算法,对于一个监督学习任务来说,其 m m个训练样本为: {(X(1),y(1)),(X(2),y(2)),⋯,(X(m),y(m))} \lef ...

  9. 数据结构与算法——堆的原理和实现

    目录 一.堆的原理 二.堆的实现 1.堆的定义 2.堆的初始化 3.向上调整算法 4.向上调整算法代码实现 5.堆的插入 6.向下调整算法 6.堆的删除 7.堆的大小 8.判断堆是否为空 总结 一.堆 ...

最新文章

  1. 重磅!Elasticsearch 8 正式发布!
  2. 【Interfacenavigation】通知概述(36)
  3. 类选择器和所作用的标签一起写为什么不起作用? - CSDN博客
  4. python线程中再起线程_多线程 - Python中的线程化
  5. oracle asin(),PLSQL ASIN用法及代码示例
  6. VTK修炼之道37:图像平滑_高斯滤波器
  7. 设计模式——UML图
  8. php怎么实现商品评论功能,php购物车功能如何实现
  9. 为什么国外程序员加班少?他们这样评价996和技术公众号
  10. python实现 Floyd算法求解最短路径距离问题
  11. python简单代码表白-表白python代码
  12. 抱薪者说 | 廿七喜得子老王为名忧,论坛聚英豪树鑫拔头筹
  13. 【IDE】【WebStorm】html排版设置head和body缩进
  14. 最热门的旅游目的地:1971年至2011年
  15. 图的遍历 —— 广度优先遍历
  16. 冰山理论(理解笔记)
  17. 手游联运平台是怎样开发的?
  18. 小白也能写前端?推荐一款超实用的app----JsHD调试器,助你写出炫酷的网页!
  19. NPN型三极管的工作原理
  20. My97DatePicker设置,包括隐藏 清空,设置最大日期等

热门文章

  1. html使用element ui_Kendo UI for jQuery使用教程:自定义小部件(二)
  2. oracle 优化分组 sql语句,Oracle SQL语句之常见优化方法 五
  3. 万物皆可傅里叶!用傅里叶变换还能画出世界名画!
  4. 太牛了,原来古人是这样铸造钱币的。。。
  5. 数学学得好,才可以发现别人发现不了的挣钱良机
  6. 现在的便签本都这么社会了!?重复写万次还能云端保存
  7. 【干货】人人都能看懂的LSTM
  8. Oracle小知识总结
  9. 图像处理前沿技术_深入浅出人工智能前沿技术—机器视觉检测,看清人类智慧工业...
  10. python双除_python2和python3 中的除法的区别