对B-树的理解

前言-为什么要使用B-树?

首先,我们正常的搜索都有一下方式:

  1. 搜索二叉树,极端场景下会退化,类似于单支,此时的效率变成了O(N);
  2. 为了解决1的问题,提出了平衡树的概念,左右子树的高度差不大于1,AVL树,红黑树。该效率为O(logN),其中map/set就是由此构建的;
  3. 更好的搜索结构则有哈希/散列表,该效率为O(1),–unordered_map/unordered_set
  4. 跳表、字典树

上面的结构都是完成内存中数据的搜索查找问题
但假设此时的数据量很多,在内存中存放不下,数据要存到磁盘中,上面的数据结构就不好了,虽然可以把内存在磁盘的地址使用AVL树来存储,查找的时间复杂度为O(logN),但是该复杂度在内存中访问非常快,在磁盘中,logN次磁盘IO访问会非常慢。 如果换成哈希表,变成O(1),在极端情况下,哈希表冲突十分厉害,一个桶中数据太多,会影响效率,并且哈希表中存在很多附带数据(表结构、节点中的指针等),数据量很大时,内存占用很多。B树则能解决这些问题。

B-树概念

B树是一种平衡的多叉树,一颗M阶(M>2)的B树,为平衡的M路平衡搜索树,可以是空树或者满足以下性质:

  1. 根节点至少有两个孩子
  2. 每个非根节点至少有M/2(向上取整)个孩子,至多有M个孩子
  3. 每个非根节点至少有M/2-1(向上取整)个关键字,至多有M-1个关键字,并且以升序排列
  4. key(1)和key(i+1)之间的孩子节点的值介于key[i]、key[i+1]之间
  5. 所有的叶子节点都在同一层

对上述性质进行总结来说:

根节点:关键字数量[1,M-1],孩子数量[2,M]
非根节点:关键字数量[M/2-1, M-1],孩子数量[M/2,M]
每个节点中,孩子的数量比关键字的数量永远要多一个

那么为什么会有这样的性质呢?结合例子来进行理解
针对根节点的数量范围分析
首先,一个关键字会有两个孩子(左孩子和右孩子),其中和相邻的关键字会共有一个孩子,即关键字1的右孩子也是关键字2的左孩子,那么孩子的数量就会比关键字的数量多一个。
在这里插入图片描述
针对非根节点的数量范围分析
假设M等于3,那么根节点的关键字数量最多只能放2个,如果放到了3个,则违反了规则,根节点最多存M-1个关键字,那么就会进行分裂,创建一个兄弟节点,右边M/2的值拷贝到兄弟节点中,中间值插入到父亲,如果没有父亲,则创建新的父亲,该值作为新的根。也就是上图右下角的节点,关键字70超出范围,则进行分裂,将70分裂为兄弟节点,50插入到父亲节点。
那么为什么分裂的时候要提中位数插入到父亲呢?
因为分裂新增一个兄弟节点,对于父亲而言,多了一个孩子,还得多一个关键字,这样才能保持孩子的数量比关键字数量多一个。
结合分裂的思想:
如果M是奇数,分裂时两边数量为M/2,中间值插入到父亲。(比如M=9,左右各为4,剩余的一个节点插入到父亲,如果没有父亲则创建)
如果M是偶数,因为两边要有一个需要插入到父亲,因此总有一边要少一个,一边是M/2,一边是M/2-1。(比如M=10,左右为5和4或者4和5,剩余一个插入到父亲,如果没有父亲则创建)
在这里插入图片描述

相关推荐

  1. BB+区别

    2024-07-15 20:24:02       53 阅读
  2. bb+区别

    2024-07-15 20:24:02       37 阅读
  3. BB+区别

    2024-07-15 20:24:02       17 阅读
  4. Promise理解

    2024-07-15 20:24:02       29 阅读
  5. MySQL中InnoDB引擎行数据过大B+存储影响

    2024-07-15 20:24:02       22 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-15 20:24:02       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-15 20:24:02       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-15 20:24:02       57 阅读
  4. Python语言-面向对象

    2024-07-15 20:24:02       68 阅读

热门阅读

  1. 用Python爬虫能实现什么?得到什么?

    2024-07-15 20:24:02       20 阅读
  2. JVM堆内存的结构,YGC,FGC的原理

    2024-07-15 20:24:02       20 阅读
  3. Spring boot 2.0 升级到 3.3.1 的相关问题 (二)

    2024-07-15 20:24:02       20 阅读
  4. LeetCode题练习与总结:寻找峰值--162

    2024-07-15 20:24:02       17 阅读
  5. Mysql数据库(一)

    2024-07-15 20:24:02       24 阅读
  6. (leetcode学习)16. 最接近的三数之和

    2024-07-15 20:24:02       19 阅读
  7. /EtherCATInfo/Descriptions/Devices/Device/SubDevice/@Hideable

    2024-07-15 20:24:02       16 阅读
  8. 零基础自学爬虫技术该从哪里开始入手?

    2024-07-15 20:24:02       19 阅读