虽是读书笔记,可是如转载请注明出处 http://segmentfault.com/blog/exploring/
.. 拒绝伸手复制党html
如下是算法导论第十八章的学习笔记算法
若是红黑树中的每一个黑结点吸取它的红子女,并把它们的子女并入自身,描述这个结果的数据结构。
(2-3-4树
)
or
假设将一棵红黑树的每个红结点 “吸取” 到它的黑色父结点中,来让红结点的子女变成黑色父结点的子女(忽略关键字的变化)。当一个黑结点的全部红色子女都被吸取后,其可能的度是多少?此结果树的叶子深度怎样segmentfault
这段整理自July's blog 和 本身的理解
磁盘读取数据(把数据从外存调入内存)是以盘块(block)为基本单位的。位于同一盘块中的全部数据都能被一次性所有读取出来。而磁盘IO代价主要花费在查找时间上。所以咱们应该尽可能将相关信息存放在同一盘块,同一磁道中,这样一次IO时间就能够。或者至少放在同一柱面或相邻柱面上,以求在读/写信息时尽可能减小磁头来回移动的次数,避免过多的查找时间。数据结构
因此,在大规模数据存储方面,大量数据存储在外存磁盘中,而在外存磁盘中读取/写入块(block)中某数据时,首先须要定位到磁盘中的某块,如何有效地查找磁盘中的数据,须要一种合理高效的外存数据结构,B 树是为了磁盘或其它存储设备而设计的一种多叉平衡查找树。函数
与红黑树不一样之处在于,B树的节点能够有许多个,从几个到几千个。不过 B 树与红黑树同样,一棵含 n 个结点的 B 树的高度也为 O(logn)
,但可能比一棵红黑树的高度小许多,由于对数的底由红黑树的2
变为t
(t为最小度数
). 由于它的分支因子比较大。因此,B 树能够在 O(logn)
时间内,实现各类如插入(insert),删除(delete)等动态集合操做。学习
B树的每一个节点根据实际状况能够包括大量信息和子女(固然是不能超过磁盘块的大小,由于咱们从磁盘上读取信息的时候通常都是按照磁盘块进行的,一个磁盘快对应一个节点,每次检索B树的时候遇到一个节点,也就对应一次磁盘的访问操做,若是一个节点大于了一个磁盘块,那么访问一个节点须要两次磁盘访问,效率就不行了,通常块的大小在 1k~4k 左右 )spa
如图 17是磁盘文件名;小红方块表示这个 17 文件内容在硬盘中的存储位置;p1 表示指向 17 左子树的指针设计
若是是一棵 m 阶的 B 树,那么有:指针
m
阶树的孩子数ceil(m / 2)
个孩子(其中 ceil(x) 是一个取上限的函数);B 树的类型和节点定义以下图所示:code
假如每一个盘块能够正好存放一个 B 树的结点(正好存放 2 个文件名)。那么一个 BTNODE 结点就表明一个盘块,而子树指针就是存放另一个盘块的地址。
下面,我们来模拟下查找文件 29 的过程:(详细见July博客)
分析上面的过程,发现须要 3 次磁盘 IO 操做和 3 次内存查找 操做。关于内存中的文件名查找,因为是一个有序表结构,能够利用折半查找提升效率。至于 IO 操做是影响整个 B 树查找效率的决定因素。
查询须要O(h)
存取的磁盘页面数
插入元素 - 检查是否存在
- 存在,不插入
- 不存在,在叶子节点插入新的元素
叶子节点空间足够(#<m-1
),插入
叶子节点空间不够(#=m-1
),插入进去,而后分裂
,中间节点上移
若是致使父节点满了,父节点再分裂;若致使根节点满了。这样致使树的高度
+1
高度为h
的树,只须要O(h)
次磁盘存取操做。
删除元素 - 检查BTree是否存在该节点
- 不存在,不删除
- 存在,删除之,而后判断:该元素是否有左右孩子
如有,则上移``孩子
中相近元素 (“左孩子最右边的节点” 或 “右孩子最左边的节点”) 到该节点 - to step *
若无,直接删除 , - to step *
step *: 若是删除以后或者移动以后,致使某节点的元素数目小于 ceil(m/2)-1
;则须要查看某相邻的兄弟节点是否丰满
(大于 ceil(m/2)-1
)
step *1. 父节点降低
一个关键字到该节点;降低
--判断兄弟 --
step *2.1 若是其某个相邻兄弟
结点中比较丰满(元素个数大于 ceil(m/2)-1
),则能够借给父结点一个元素,即将最丰满的相邻兄弟结点中上移
到父节点中 上调
step *2.2 若是其相邻兄弟
都刚脱贫,即借了以后其结点数目小于 ceil(m/2)-1
,则该结点与其相邻的某一兄弟结点进行 合并
成一个结点,以此来知足条件 合并