磁盘作为辅存,它的容量要比内存大得多,但是速度也要慢许多,下面就是磁盘的的结构图:

磁盘驱动器由一个或多个盘片组成,它们以固定的速度绕着主轴旋转,数据存储于盘片的表面,磁盘驱动器通过磁臂末尾的磁头来读写盘片。礠臂可以将磁头向主轴移近或移远。当一个磁头处于静止的时候,它下面经过的磁盘表面称为磁道。

磁盘之所以比主存要慢,是因为它有机械运动的部分:盘片旋转和磁臂运动。为了摊还机械移动所花费的等待时间,磁盘会一次存取多个数据项。磁盘上的数据被组织成页面。每次磁盘读写的数据都是以页面为单位。

本章考虑运行时间主要考虑:磁盘存取次数以及CPU时间。尽管磁盘读写时间依赖于当前磁道和所需磁道之间的距离以及磁盘的初始旋转状态,但是仍然使用读写的页数作为磁盘存取时间的近似值。

在一个典型的B树应用中,需要处理的数据非常大,以至于所有数据无法一次装入主存。通过下面的代码对磁盘操作进行建模。设x为指向一个对象的指针,如果该对象在主存中,那么可以像平时一样引用该对象的属性。如果x所指的对象不在主存中,那么在引用该对象的属性之前,需要先执行DISK-READ(x),将该对象读入主存中。(如果对象已经在主存中,则DISK-READ(x)是个空操作)。同样,如果x所指的对象的属性改变了,则需要通过DISK-WRITE(x)写入磁盘:

x = a pointer  to some object

DISK-READ(x)

operations  that access and/or modify the attributes of x

DISK-WRITE(x)       // omitted if no attributes of x were  changed

other operations that access but do not modify attributes of x

一个B树算法的运行时间主要由DISK-READ和DISK-WRITE操作的次数决定,希望这些操作能够读写尽可能多的信息。因此,一个B树节点通常和一个完整磁盘页一样大。B树就是为磁盘设计的一种平衡搜索树。许多数据库系统使用B树或者B树的变种来存储信息。

B树类似于红黑树,不同之处在于B树可以有很多孩子,也就是B树的分支因子可以很大,所以对于n个节点,B树的严格高度要比红黑树小得多。下图就是一个简单的B树:

如果B树的内部节点x包含x.n个关键字,则节点x就有x.n+1个孩子。节点x中的关键字就是分隔点,他把所有的关键字分隔为x.n+1个子域,每个子域都由x的一个孩子处理。

一:B树的定义

一颗B树具有下面的性质:

1:每个节点x有下面属性:

4:所有叶节点具有相同的深度,树的高度为h。

5:每个节点包含的关键字个数有上界和下界。用固定整数t>=2(t称为B树的最小度数)表示:

a:除了根节点之外,每个节点至少包含t-1个关键字,所以除了根节点之外,每个内部节点至少有t个孩子。

b:每个节点至多包含2t-1个关键字,因此,每个内部节点最多有2t个孩子,如果一个节点有2t-1个关键字时,称该节点是满的。

比如,如果t=2,则每个内部节点有2,3,或者4个孩子。B树上的大多数操作所需的磁盘存取次数与树的高度成正比,对于B树的高度,有下面的定理:

如果n>=1,那么包含n个关键字,高度为h,最小度数为t>=2的B树满足:h<=

证明如下:B树的根至少包含一个关键字,其他节点至少包含t-1个关键字,所以B树在深度为1,至少包含2个节点,在深度2,至少包含2t个节点,在深度3,至少包含2
个节点。所以,在深度h,至少包含2个节点。所以有:n>=
1+(t-1)  = 2
-1。所以有:h<= 。注意;n表示关键字的个数,而非节点个数。

二:B树上的基本操作

讨论B树的基本操作如B-TREE-SEARCH, B-TREE-CREATE和B-TREE-INSERT之前,做如下约定:

a:B树的根结点始终在主存中,因而无需对根做DISK-READ;但是,每当根结点被改变后,都需要对根结点做一次DISK-WRITE。

b:任何被当作参数的结点被传递之前,要先对它们做一次DISK-READ。

1:搜索

B-TREE-SEARCH操作,输入时一个指向某子树根节点x的指针,以及要搜索的关键字k。因此,顶层调用的形式为B-TREE-SEARCH(T.root, k)。如果k在B树中,那么B-TREE-SEARCH返回的是由节点y和使得y.
 == k的下标组成的序对(y, i);否则返回NULL,代码如下:

B-TREE-SEARCH过程,访问的磁盘页面数为O(h) = O(),总的CPU时间为O(th)
= O()

2:创建一个空的B树

为构造一颗B树T,先用B-TREE-CREATE来创建一个空的根节点,然后调用B-TEE-INSERT来添加关键字:

B-TREE-CREATE需要O(1)次的磁盘操作和O(1)的CPU时间。

3:插入关键字

B树中插入关键字要比二叉搜索树中的插入复杂。首先要查找插入新关键字的叶节点的位置,然而不同于二叉搜索树的插入,在B树中,不能简单的创建一个新的叶节点,因为会破坏B树的性质,所以要将关键字插入一个已经存在的叶节点上。

由于不能将新的关键字插入一个满的叶节点,所以需要将满的节点y(有2t-1个关键字)按照中间关键字y.分裂为两个各含t-1个关键字的节点。中间关键字被提升到y的父节点。但是如果y的父节点也是满的,则必须在插入新的关键字之前就将其分裂。

为了插入新的关键字,可以从根到叶节点的向下过程中将一个关键字插入,当沿着树向下查找新的关键字所属位置时,就分裂沿途遇到的每个满节点。因此,每当要分裂一个满节点时,可以确保它的父节点不是满的。

B-TREE-SPLIT-CHILD的输入是一个非满的内部节点x,以及下标i,这个下标表示的x的子节点x.
为满子节点。要分裂一个根,则首先创建一个新的节点,然后使根成为该节点的孩子,此时在调用B-TREE-SPLIT-CHILD。此时树的高度加1,分裂时树长高的唯一途径。B-TREE-SPLIT-CHILD代码如下:

B-TREE-SPLIT-CHILD占用的CPU时间为Ө(t),执行O(1)次磁盘操作。下图展示了该过程:

在一裸高度为h的B树T中,插入一个关键字k的操作是在沿树下降的过程中一次完成的。共需要O(h)次磁盘存取,所需的CPU时间为O(th)
= O()。B-TREE-INSERT代码如下:

其中的B-TREE-INSERT-NONFULL代码如下:

三:从B树中删除关键字

B树上的删除操作与插人操作类似,只是稍微有点复杂,因为一个关键字能够从任意一个结点中删除,而不只是可以从叶子中删除:从一个内部结点中删除关键字时,需要重新安排这个结点的子女;必须防止因删除操作而导致树的结构违反B树性质,必须保证一个结点不会在删除期间变得太小(只有根结点除外)。

过程B-TREE-DELETE从以x为根的子树中删除关键字k。这个过程必须保证了无论在何时,x的关键字个数都至少等于最小度数t。注意这个条件要求比通常的B树中最少的关键字数多1个的关键字。这是因为该过程在递归下降时,需要把x的关键字移动到子节点中。

如果,同时也保证了树根必须包含至少一个关键字(除非树是空的)的性质。

下面,我们来大致描述一下删除操作的工作过程:

1:如果关键字k在结点x中,而且x是个叶结点。则从x中删除k,算法结束;

2:如果关键字k在结点x中而且x是个内结点,则作如下操作:

a:如果结点x中前于k的子结点y包含至少t个关键字,则找出k在以y为根的子树中的前驱k' 。递归地删除k' ,并在x中用k’取代k。

b:对称地,如果y的关键字个数少于t,则检查结点x中位于k之后的子结点z。如果z包含至少t个关键字,则找出k在以z为根的子树中的后继k’。递归地删除k’,并在x中用k’取代天k。

上述两种情况本质上相同,针对2a,如下图:

将结点x中的k替换为 后,因为y的关键字个数为t,所以可以递归的调用B-TREE-DELETE(y, k')即可。

c:否则,如果y和z都只有t-1个关键字,则将k和z中所有关键字合并进y,使得x失去k和指向z的指针,这使y包含2t-1个关键字。然后,释放z并递归的将k从y中删除。

如下图:

结点y和z合并,成为新的y结点,同时将x中关键字k并入新的y结点作为中间节点,此时y包含2t-1个关键字,具有2t个子节点,所以可以递归的调用B-TREE-DELETE(y,k)即可。

3:如果关键字k不在内结点x中。则确定包含k的的子树的根x.
 (如果k确实在树中的话)。如果x.有t个关键字,则递归的调用B-TREE-DELETE(x.,
k)即可。

如果x. 只有t-1个关键字,执行步骤3a或3b以保证我们降至一个包含至少t个关键字的结点,然后,通过对x的某个合适的子结点进行递归而结束:

a:如果x.
只包含t-1个关键字,但它的一个相邻兄弟包含至少t个关键字.则将x中的某一个关键字降至x.中,将x.
的相邻左兄弟或右兄弟中的某一关键字升至x,将该兄弟中合适的子女指针移到x. 中,这样使得x.
增加一个额外的关键字。

如下图:

经过上面的转换之后,x. 有了t个关键字,则递归的调用B-TREE-DELETE(x.,
k)即可。

b:如果x.
以及x.
的所有相邻兄弟都包含t-1个关键字,则将x.
与一个兄弟合并,即将x的一个关键字移至新合并的结点,使之成为该结点的中间关键字。

如下图:

经过上面的转换之后,x. 包含2t-1个关键字,所以可以递归的调用B-TREE-DELETE(x.,k)即可。

因为一棵B树中的大部分关键字都在叶结点中,我们可以预期在实际中,删除操作主要是用于从叶结点中删除关键字。这样B-TREE-DELETE过程只要沿树下降一趟即可,而无需任何回溯。但是,当删除某内结点中的一个关键字时,该程序也沿树下降一趟,但可能还要返回删除了关键字的那个结点,以用其前驱或后继来取代被删除的关键字(情况2a和情况2b}。

这个过程虽然看似复杂,但对一棵高度为h的B树,它只需O(h)次磁盘存取操作,因为在递归调用该过程之间,仅需O(1)次对DISK-READ和DISK-WRITE的调用。所需CPU时间为O(th)
= O( )。

算法导论笔记:18B树的更多相关文章

  1. MIT算法导论笔记

    详细MIT算法导论笔记 (网络链接) 第一讲:课程简介及算法分析 (Sheridan) 第二讲:渐近符号.递归及解法  (Sheridan) 第三讲:分治法(1)(Sheridan) 第四讲:快排及随 ...

  2. "《算法导论》之‘树’":二叉查找树

    树的介绍部分摘取自博文二叉查找树(一).二叉查找树(二).二叉查找树. 1. 树的介绍 1.1 树的定义 树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合. 把它叫做“ ...

  3. 算法导论笔记——第二十章 van Emde Boas树

    当关键字是有界范围内的整数时,能够规避Ω(lglgn)下界的限制,那么在类似的场景下,我们应弄清楚o(lgn)时间内是否可以完成优先队列的每个操作.在本章中,我们将看到:van Emde Boas树支 ...

  4. 算法导论笔记——第十八章 B树

    18.1 B树的定义  18.2 B树的基本操作 与一棵二叉搜索树一样,可以在从树根到叶子这个单程向下过程中将一个新的关键字插入B树中.为了做到这一点,当沿着树向下查找新的关键字所属位置时,就分裂沿途 ...

  5. MIT公开课:算法导论 笔记(一)

    课程链接:http://open.163.com/special/opencourse/algorithms.html 第一课:算法分析基础 1.介绍插入排序与归并排序,计算并比较最坏运行时间 2.算 ...

  6. 【算法导论】B树

          一棵B树T是具有如下性质的有根树(设根为root): 1.每个节点x有一下域: (a)num,当前存储在节点x的关键字个数,关键字以非降序存放,因此key[i]<=key[i+1]& ...

  7. "《算法导论》之‘树’":AVL树

    本文关于AVL树的介绍引自博文AVL树(二)之 C++的实现,与二叉查找树相同的部分则不作介绍直接引用:代码实现是在本文的基础上自己实现且继承自上一篇博文二叉查找树. 1.AVL树的介绍 AVL树是高 ...

  8. B树——算法导论(25)

    B树 1. 简介 在之前我们学习了红黑树,今天再学习一种树--B树.它与红黑树有许多类似的地方,比如都是平衡搜索树,但它们在功能和结构上却有较大的差别. 从功能上看,B树是为磁盘或其他存储设备设计的, ...

  9. 算法导论第十八章 B树

    一.高级数据结构 本章以后到第21章(并查集)隶属于高级数据结构的内容.前面还留了两章:贪心算法和摊还分析,打算后面再来补充.之前的章节讨论的支持动态数据集上的操作,如查找.插入.删除等都是基于简单的 ...

随机推荐

  1. bzoj月赛1805

    题目在最后,FG还不会做,等着$NicoDafaGood$和$Achen$给我讲 A 对于每一个质因子建一棵线段树,直接查询就好了 主要是看到所有数的大小都不是很大,然后质因子最多只有log个,复杂度 ...

  2. 使用jquery-file-upload实现上传图片时报empty file upload result错误

    原因:后台返回的json格式没有严格按照github中的格式返回 参考:https://groups.google.com/forum/#!topic/jquery-fileupload/0q8PN2 ...

  3. 工控安全入门(二)—— S7comm协议

    在上一次的文章中我们介绍了施耐德公司的协议modbus,这次我们把目标转向私有协议,来看看另一家巨头西门子的S7comm.首先要说明,这篇文章中的内容有笔者自己的探索,有大佬们的成果,但由于S7com ...

  4. NOIP模拟17.10.12

    T1 临江仙 旧梦 题目背景 闻道故园花陌,今年奼紫嫣红.扬帆直渡水千重.东君何解意,送我一江风. 还是昔时庭院,终得醉卧花丛.残更惊醒月明中.流光如旧岁,多少梦成空. 题目描述 #define go ...

  5. python设计模式整理

    设计模式的定义:为了解决面向对象系统中重要和重复的设计封装在一起的一种代码实现框架,可以使得代码更加易于扩展和调用 四个基本要素:模式名称,问题,解决方案,效果 六大原则: 1.开闭原则:一个软件实体 ...

  6. bnd.bnd属性文件格式

    1.Header以大写字母开头 Bundle-Name: StoreAdminProductsTool 2.Instruction以-和小写字母开头 -sources: true 3. Macro形式 ...

  7. scala实现定时任务的方法

    /** * ScheduledExecutorService是从Java SE5的java.util.concurrent里,做为并发工具类被引进的,这是最理想的定时任务实现方式. * 它有以下好处: ...

  8. Wireshark 基本使用方法

    学习于: http://www.cnblogs.com/TankXiao/archive/2012/10/10/2711777.html

  9. 【转载】遗传算法及matlab实现

    摘自https://www.cnblogs.com/LoganChen/p/7509702.html 1.遗传算法介绍 遗传算法,模拟达尔文进化论的自然选择和遗产学机理的生物进化构成的计算模型,一种不 ...

  10. koa2路由

    注意:必须导出 文档地址:https://npm.taobao.org/package/koa-router 例: const router = require('koa-router')() rou ...