B-树的理论分析

Posted 顧棟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了B-树的理论分析相关的知识,希望对你有一定的参考价值。

B-树

理论部分来自《数据结构 (C语言版)》 严蔚敏

背景知识

B-树是一种平衡的多路查找树,B-树其实就是B树,因为英文是B-Tree,翻译成了B-树。

B-树的数据结构常用于数据库索引技术和文件索引。由于数据库的索引是存储在磁盘上的,当数据量的比较大的时候,无法将整个索引一次全部加载到内存中,只能逐一加载磁盘页,使用B-树可以减少磁盘的I/O,提高查询效率,树的阶数取决于磁盘页的大小。非关系数据库MongoDB使用的B-树。

B-树的定义与特点

一颗 m m m阶的B-树需要满足特性

  1. 树中每个结点至多 m m m​​棵子树

  2. 若根结点不是叶子结点,则至少有两棵子树

  3. 除根之外的所有非叶子结点至少有 ⌈ m 2 ⌉ \\lceil \\fracm2 \\rceil 2m棵子树( m 2 \\fracm2 2m的值向上取整,不比 m 2 \\fracm2 2m小的最小整数)

  4. 所有的非叶子结点中包含了以下信息数据

    n , A 0 , K 1 , A 1 , K 2 , A 2 , . . . , K n , A n n,A_0,K_1,A_1,K_2,A_2,...,K_n,A_n n,A0,K1,A1,K2,A2,...,Kn,An​)

    其中 K i ( i = 1 , . . . , n ) K_i(i=1,...,n) Ki(i=1,...,n)​​​​​为关键字,且 K i < K i + 1 ( i = 1 , . . . , n − 1 ) K_i<K_i+1(i=1,...,n-1) Ki<Ki+1(i=1,...,n1)​​​​; A i ( i = 0 , . . . , n ) A_i(i=0,...,n) Ai(i=0,...,n)​​​​为指向子树结点的指针,且指针 A i − 1 A_i-1 Ai1​​​​所指子树中所有结点的关键字均小于 K i ( i = 1 , . . . , n ) K_i(i=1,...,n) Ki(i=1,...,n)​​​​, A n A_n An​​​​所指子树所有结点的关键字均大于 K n K_n Kn​​, n ( ⌈ m 2 ⌉ − 1 ≤ n ≤ m − 1 ) n(\\lceil \\fracm2 \\rceil-1 \\leq n \\leq m-1) n(2m1nm1)​​为关键字的个数(或 n + 1 n+1 n+1​​​​​​为子树个数)。

    ​ 简单理解就是

    • 非终端节点中包含了 关键字的个数指向其子树结点的指针列表,关键字的值列表,指针与关键字交替存放。
    • 关键字是按从左往右的方向由小到大排序存放,指针指向的结点(即子树结点)的所有关键字,都大于该指针前面的关键字且小于指针之后的关键字。
    • 关键字的个数的取值范围 ⌈ m 2 ⌉ − 1 ≤ n ≤ m − 1 \\lceil \\fracm2 \\rceil-1 \\leq n \\leq m-1 2m1nm1​。
  5. 所有的叶子结点都出现在同一层次上,且不带信息(可以看做是外部结点或查询失败的结点,实际上这些结点不存在,指向这些结点的指针都为null)。

    ​ 这句话与代码里的叶子结点困惑我很久,其实这里的叶子结点与代码实现的叶子结点不是一个意思,代码中的叶子节点,从这句话的角度来说,其实是叶子结点的上一层,为了实现易于实现,在代码中定义成叶子结点。

什么是B-树的阶?

B-树中一个结点的子结点数目的最大值,用m表示,假如最大值为3,则为3阶。

查找的分析

在B-树中查找有两种操作

  1. 查找结点

    B-树是存在磁盘中 该查找是在磁盘上进行的

  2. 在结点中找关键字

    在磁盘上找到P结点所指的指针后,将结点信息加载入内存,在利用顺序查找或者二分查找找到关键字。

内存的查找速度高于磁盘的查找速度,那么查找的效率关键在于B-树的深度,那么包含N个关键字的m阶B-树的最大深度是什么?

l = l o g ⌈ m 2 ⌉ ( N + 1 2 ) + 1 l=log_\\lceil \\fracm2 \\rceil^(\\fracN+12)+1 l=log2m(2N+1)+1

如何证明这个公式 ?如下

深度为 l + 1 l+1 l+1 m m m阶B-树的最少结点数

层数最少结点数备注
11根结点
22
32* ⌈ m 2 ⌉ \\lceil \\fracm2 \\rceil 2m除了根结点,每个非终端结点的至少有 ⌈ m 2 ⌉ \\lceil \\fracm2 \\rceil 2m棵子树,可以看做2* ( ⌈ m 2 ⌉ ) ( 3 − 2 ) (\\lceil \\fracm2 \\rceil)^(3-2) (2m)(32)
42* ( ⌈ m 2 ⌉ ) 2 (\\lceil \\fracm2 \\rceil)^2 (2m)2可以看做2* ( ⌈ m 2 ⌉ ) ( 4 − 2 ) (\\lceil \\fracm2 \\rceil)^(4-2) (2m)(42)
·········
l + 1 l+1 l+12* ( ⌈ m 2 ⌉ ) ( l − 1 ) (\\lceil \\fracm2 \\rceil)^(l-1) (2m)(l1)可以看做2* ( ⌈ m 2 ⌉ ) ( l + 1 − 2 ) (\\lceil \\fracm2 \\rceil)^(l+1-2) (2m)(l+12)

若m阶的B-树中有N个关键字,则叶子结点的个数为N+1,那么有
2 ∗ ( ⌈ m 2 ⌉ ) ( l − 1 ) ≤ N + 1 2*(\\lceil \\fracm2 \\rceil)^(l-1) \\leq N+1 2(2m)(l1)N+1
反之
l ≤ l o g ⌈ m 2 ⌉ ( N + 1 2 ) + 1 l \\leq log_\\lceil \\fracm2 \\rceil^(\\fracN+12)+1 llog2m(2详解 B树

详解 B树

详解 B树

讲透学烂二叉树:图中树的定义&各类型树的特征分析

层次分析法(AHP)Python实现

Offer[26] 树的子结构