B树(B-树)
1、什么是B树(B-树)?
B树是一种m阶树,m>=2
性质:
1)树中每个结点至多m个孩子;
2)对于根结点,子树个树取值范围为[2,m],关键字个数范围[1,m-1];
3)对于非根非叶结点,子树个数取值范围为[ceil(m/2),m],关键字个数范围为[ceil(m/2)-1,m-1];
4)所有叶子结点都出现在同一层。
5)每个非叶子结点中包含n个关键字信息:(n, P0, K1, P1, K2, P2, ... , Kn, Pn)。
n为关键字的个数,且有 [ceil(m/2)-1] <= n <= m-1
Ki为关键字,且按升序排序
Pi为指向子树的接点,且 K(i-1) <= P(i-1) 指向子树的所有结点关键字 <=Ki
三阶B树
2)3)的应用
如果B树结点的最小度数为固定整数t>=2,有
a) 非根结点至少 t-1个关键字,非根非叶结点至少t个子女
b)每个结点至多2t-1个关键字,每个非根非叶结点至多2t个子女
c)综上所述根结点关键字个数范围为:[1, 2*t-1],非根结点关键字个数范围为:[t-1,2*t-1]
2、B树复杂度与高度
B树的高度:
根为1个结点,第二层至少为2个结点,第三层至少为2t个结点,第四层至少2t*t个结点
将所有最小结点相加,推导过程:n>= 1+2+2t+2t^2+ ... +2t^(h-1)=3+2t (t^h-1)/(t-1)>=2t^(h-1)+1
最后推出的结果为
h<=log((n-1)/2)
3、操作
这里只给出插入删除操作,查找操作相对简单的多 这里不做解释
1)B-树的插入操作(重点判断是否满足n<=m-1)
a.利用前述的B-树的查找算法查找关键字的插入位置。若找到,则说明该关键字已经存在,直接返回。否则查找操作必失败于某个最低层的非终端结点上。
b.判断该结点是否还有空位置。即判断该结点的关键字总数是否满足n<=m-1。若满足,则说明该结点还有空位置,直接把关键字k插入到该结点的合适位置上。若不满足,说明该结点己没有空位置,需要把结点分裂成两个。
分裂的方法是:生成一新结点。把原结点上的关键字和k按升序排序后,从中间位置把关键字(不包括中间位置的关键字)分成两部分。左部分所含关键字放在旧结点中,右部分所含关键字放在新结点中,中间位置的关键字连同新结点的存储位置插入到父结点中。如果父结点的关键字个数也超过(m-1),则要再分裂,再往上插。直至这个过程传到根结点为止。
2)B树的删除
a)利用B树查找算法找出关键字所在的结点,然后根据结点所在的位置判断是否为叶子结点
b)若为非叶结点,且被删关键字为该结点中第i个关键字key[i],则可从指针son[i]所指向的子树中找出最小关键字Y,代替key[i]的位置,然后在叶结点中删去Y,把非叶结点的删除化为叶结点的删除。
叶结点删除一个关键字的方法:
三种不同情况:
(1)如果被删关键字所在结点的原关键字个数n>ceil(m/2),则说明删去该关键字后该结点仍满足B树的定义,这种情况下直接删除即可;
(2)如果被删除关键字所在结点的关键字个数n等于ceil(m/2)-1,说明删去该关键字后该结点将不满足B树的定义,需要调整:
如果其左右兄弟结点中有“多余”的关键字,即与该结点相邻的左(右)兄弟结点中的关键字数目大于ceil(m/2)-1,则可将左(右)兄弟结点中最大(小)的结点上移至双亲结点,而将双亲结点中大(小)于该上移关键字的关键字下移至被删关键字所在结点中。
(3)如果左右兄弟结点中没有多余的关键字,即左右兄弟结点中关键字的数目均等于ceil(m/2)-1。
需要调整:
在删除关键字后,该结点中剩余的关键字加指针,加上双亲结点中的关键字(该关键字为结点与兄弟结点的分割者),合并到兄弟结点中去。
B树(B-树)的更多相关文章
- BZOJ 3110: [Zjoi2013]K大数查询 [树套树]
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6050 Solved: 2007[Submit][Sta ...
- BZOJ4170 极光(CDQ分治 或 树套树)
传送门 BZOJ上的题目没有题面-- [样例输入] 3 5 2 4 3 Query 2 2 Modify 1 3 Query 2 2 Modify 1 2 Query 1 1 [样例输出] 2 3 3 ...
- Atitit 常见的树形结构 红黑树 二叉树 B树 B+树 Trie树 attilax理解与总结
Atitit 常见的树形结构 红黑树 二叉树 B树 B+树 Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 ...
- bzoj3262: 陌上花开(树套树)
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- bzoj3295: [Cqoi2011]动态逆序对(树套树)
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- BZOJ 3110 k大数查询 & 树套树
题意: 有n个位置,每个位置可以看做一个集合,现在要求你实现一个数据结构支持以下功能: 1:在a-b的集合中插入一个数 2:询问a-b集合中所有元素的第k大. SOL: 调得火大! 李建说数据结构题能 ...
- HDU 5877 dfs+ 线段树(或+树状树组)
1.HDU 5877 Weak Pair 2.总结:有多种做法,这里写了dfs+线段树(或+树状树组),还可用主席树或平衡树,但还不会这两个 3.思路:利用dfs遍历子节点,同时对于每个子节点au, ...
- BZOJ 3110 树套树 && 永久化标记
感觉树套树是个非常高深的数据结构.从来没写过 #include <iostream> #include <cstdio> #include <algorithm> ...
- 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组
涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...
- 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))
函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...
随机推荐
- 修改cookie
查看本地cookie方法一:点击 地址栏前面的 感叹号 !方法一:F12-->network->回车 请求一下 地址栏-->.出现的地址-->点击. header cookie ...
- CoreJavaE10V1P3.4 第3章 Java的基本编程结构-3.4 变量
1.在Java中,每一个变量都必须有一个类型,在变量声明是,类型必须在变量名之前.示例如下: double salary; int vacationDays; long earthPopulation ...
- html css jquery 回到顶部按钮
今天做了个回到顶部的功能,在这里记录一下,有需要可以拿去试试! CSS部分,很简单就一个class /*回到顶部*/ .back-top { position: fixed; right: 15px; ...
- MyBatis 3 与 Spring 4 整合关键
MyBatis 3 与 Spring 4 整合关键 MyBatis与Spring整合,首先需要一个Spring数据源.其次有两个关键,配置sqlSessionFactory时需要配置扫描sql映射xm ...
- OSI七层模型详解
OSI 七层模型通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯,因此其最主要的功能就是帮助不同类型的主机实现数据传输 . 完成中继功能的节点通常称为中继系统.在OSI七层模型中,处于 ...
- 单向链表仿LinkedList
public class ChainTable { private Node firstNode;//第一个节点 private Node lastNode;//最后一个节点 private int ...
- Python学习笔记——基础篇【第二周】——解释器、字符串、列表、字典、主文件判断、对象
目录 1.Python介绍 2.Python编码 3.接受执行传参 4.基本数据类型常用方法 5.Python主文件判断 6.一切事物都是对象 7. int内部功能介绍 8.float和long内 ...
- NEUQ1055谭浩强C语言(第三版)习题6.11
//迭代公式不是很理解,写出来算了.. #include <stdio.h> #include <math.h> int main() { double x0,x1; int ...
- ios开发的系统兼容性问题解决
对于系统中过时的方法或者是为了向下兼容兼容不同的版本使用最新的方法都要判断当前的系统版本号,在进行方法的调用 1.系统方法过时的注释 ````objc - (void)imagePickerContr ...
- String 类上的常用操作
java 中String 类上的常用操作: 首先创建对象 String line = new String("String demo"); String line2 = new ...