参考资料:算法导论 - 18章 - B树
先来谈一谈磁盘,
磁盘有两个机械运动的部分:盘片旋转 和 磁臂震动。
为了摊还机械移动所花费的等待时间,磁盘会一次存取多个数据项而非一个。信息被分为一系列相等大小的在柱面内连续出现的位页面(page),并且每个磁盘读或写一个或多个完整的页面。
我们在此只考虑两类运行时间:
1)磁盘存取次数
2)CPU计算时间
(注:磁盘存取时间并不是常量——它依赖于当前磁道和所需磁道之间的距离和磁盘的初始旋转状态。但是,我们仍然使用读或写的页数作为磁盘存取总时间的度量近似值。)
B树算法将所需页面从磁盘复制到主存,然后执行修改操作,然后写回。在任何时刻,B树算法都只需在主存中保持一定数量的页面。
由于在大多数系统中,一个B树算法的运行时间主要由它所执行的 DISK-READ 和 DISK-WRITE 操作的次数决定,所以我们希望这些操作能够读或写尽可能多的信息。因此,一个B树结点通常和一个完整磁盘页一样大,并且磁盘页的大小限制了一个B树结点可以含有的孩子数量。
根结点持久地保存在主存中。
事实上,我们将任何与关键字相连的“卫星数据”与关键字一样存放在同一个结点中,不过该卫星数据是一个指针,这个指针指向存放该关键字的卫星数据的磁盘页。
一个常见的B树变种,称为B+树,它把所有的卫星数据都存储在叶结点中,内部结点只存放关键字和孩子指针,因此最大化了内部结点的分支因子。
定义:
一棵B树
T
T
是具有以下性质的有根树(根为 )
1. 每个节点
x
x
有下面属性:
a.
x.n
x
.
n
,当前存储在结点
x
x
中的关键字个数。
b.
x.n
x
.
n
个关键字本身
x.key1, x.key2, ..., x.keyx.n
x
.
k
e
y
1
,
x
.
k
e
y
2
,
.
.
.
,
x
.
k
e
y
x
.
n
,以非降序排列,使得
x.key1≤x.key2≤ ...≤x.keyx.n
x
.
k
e
y
1
≤
x
.
k
e
y
2
≤
.
.
.
≤
x
.
k
e
y
x
.
n
。
c.
x.leaf
x
.
l
e
a
f
,一个布尔值。如果
x
x
是叶结点,则为TRUE,如果 为内部结点,则为FALSE。
2. 每个内部结点还包含 x.n+1 x . n + 1 个指向其孩子的指针 x.c1, x.c2, ..., x.cx.n+1 x . c 1 , x . c 2 , . . . , x . c x . n + 1 。叶结点没有孩子,所以他们的 ci c i 属性没有定义。
3. 关键字 x.keyi x . k e y i 对存储在各子树中的关键字范围加以分割:如果 ki k i 为任意一个存储在以 x.ci x . c i 为根的子树中的关键字,那么 k1≤x.key1≤k2≤x.key2≤...≤x.keyx.n≤kx.n+1 k 1 ≤ x . k e y 1 ≤ k 2 ≤ x . k e y 2 ≤ . . . ≤ x . k e y x . n ≤ k x . n + 1
4. 每个叶结点具有相同的深度,即树的高度 h h 。
5. 每个叶结点所包含的关键字个数有上界和下界。用一个被称为B树的最小度数(minimum degree)的固定整数
t≥2
t
≥
2
来表示这些界:
a. 除了根结点以外的每个结点必须至少有
t−1
t
−
1
个关键字。因此除了根结点以外每个内部结点至少有
t
t
个孩子。如果树非空,根结点至少有一个关键字。
b.每个结点至多可包含
2t−1
2
t
−
1
个关键字。因此,一个内部结点至多可有
2t
2
t
个孩子,此时称该结点是满的。
B树的高度
定理:对于一棵包含
n
n
个关键字,高度为 ,最小度数
t≥2
t
≥
2
的B树
T
T
,有
h≤logtn+12
h
≤
l
o
g
t
n
+
1
2