前面咱们已经介绍了BST AVL树 BRT,那么,为何要B树和B+树呢?他们和以前介绍的三种树有何区别?
其实最明显的差别体如今多叉上,前面介绍的三种树都是二叉树。而B树和B+树是多路查找树,目的是优化磁盘访问的速度。以前介绍的三种树是索引树,节点直接的链接能够理解为指针,即每一个节点在磁盘中散列存储,像这样
想要访问红色节点,须要先访问绿色节点,根据绿色节点的左子树索引查找到红色节点位置,再访问红色节点。
咱们看下以前三种树的磁盘访问
假设访问以下的树的节点10
第一次访问
第二次访问
第三次访问
第四次访问
不难看出,一个节点的访问磁盘的次数取决于该节点在树上的高度。程序员
一个m阶的B树具备以下几个特征:(m阶中的m能够理解为B树的分叉数,好比5阶B树最大分叉是5)web
这是一个B树
但实际上应该是这样的
每一个节点应该有n个数据域和n+1个指针域组成,叶子节点的指针域都为空。但为了做图简单,就不将指针域画出来了
实际m阶B树节点结构以下:
除了叶子节点,其他节点的指针域能够经过双亲节点或者孩子节点的索引看出来。数据库
以节点2,6为例,咱们看到
1<2
2<3<5<6
6<8微信
B树也是一种自平衡树
插入分如下几种状况
1.能够直接插入的状况
2.插入后破环平衡(即破环B树的定义中的任意一个性质),须要进行分裂
删除
1.能够直接删除
2.直接删除后破环平衡,先向左右子树“借”节点
3.直接删除后破环平衡,左右子树“借”不到节点,合并子树
插入删除操做比较复杂,具体示例请参照参考连接svg
以前我看了B树查找的过程,那么在B+树中是如何查找元素3呢?
一共进行了3次IO
首先,因为B+树只有根节点存储了元素数据,因此必须查到叶子节点。其次因为非叶子节点只存储索引,因此能够存储的索引树更多,可以使得B+树的高度更低,IO次数更少。性能
咱们看下B树的范围查找(3-11)
自顶向下,查找到范围的下限(3)–>中序遍历到元素6–>中序遍历到元素8–>中序遍历到元素9–>中序遍历到元素11,遍历结束优化
一样的元素构成的B+树的相同范围查找以下
自顶向下,查找到范围的下限(3)–>经过链表指针,遍历到元素6, 8–>经过链表指针,遍历到元素9, 11,遍历结束
因此说,相比于B树 B+树的优点有:编码
1.单一节点存储更多的元素,使得查询的IO次数更少。(单一节点存储更多的元素是由于B+的非叶子节点不存储数据,存的是索引)设计
2.全部查询都要查找到叶子节点,查询性能稳定。(一样是由于非叶子节点不存储数据,数据只有叶子节点有)3d
3.全部叶子节点造成有序链表,便于范围查询。
简称 | 特色 | 平衡性 | 查找性能 | 插入 | 删除 | 优点 | 应用 | |
二叉搜索树 | BST | 索引树,因为构建不稳定,查找效率不稳定 | 无 | 不稳定,跟具体构建树相关,最好O(logn),最差O(N) | 直接插入 | 删除的是叶子节点或只有左或右子树比较简单,如同时存在左右子树,那么要找到前驱或后继代替原先节点,再删除 | 性能高于线性查找 | 暂未找到,欢迎补充 |
平衡二叉树 | AVL | 索引树,BST进化版,自平衡,查找效率稳定 | 有 | 最好最坏都是O(lgn) | 最多须要2次旋转 | 最多须要lgN次旋转(参考,本人未证明) | 高度平衡,进一步提高查询效率 | 暂未找到,欢迎补充 |
红黑树 | RBT | 索引树,BST进化版,自平衡,查找效率相对稳定 | 有 | 基本维持在O(lgn),最坏比AVL略差(2lg(n+1)) | 最多须要2次旋转,3次变色 | 最多须要3次旋转(参考,本人未证明) | 自平衡,进一步提高查询效率 | Java中TreeSet和TreeMap,JDK 8之后,HashMap的设计 |
B树 | ^ | 多路查找树,提高IO效率,索引树进化而来 | 有 | IO次数取决于高度,减小IO次数 | 1.能够直接插入的状况2.插入后破环平衡,须要进行分裂 | 1.能够直接删除2.直接删除后破环平衡,先向左右子树“借”节点3.直接删除后破环平衡,左右子树“借”不到节点,合并子树 | 下降IO次数 | 文件系统索引和部分非关系型数据库,如MongoDB |
B+树 | ^ | 多路查找树,提高IO效率,B树进化版 | 有 | 进一步减小IO次数 | 相似B树 | 相似B树 | 进一步下降IO次数,范围查询方便,查询性能稳定 | 大多关系型数据库使用B+树做为索引 |