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。

需要调整:

在删除关键字后,该结点中剩余的关键字加指针,加上双亲结点中的关键字(该关键字为结点与兄弟结点的分割者),合并到兄弟结点中去。

时间: 2024-10-17 10:34:51

B树(B-树)的相关文章

剑指Offer——Trie树(字典树)

剑指Offer--Trie树(字典树) Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高. Trie的核心思想是空间换时间.利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的. Trie树也有它的缺点,Trie树的内存消耗非常大.当然,或许用左儿子右兄弟的方法建树的话,可能会好点.可见,优

BZOJ_3196_二逼平衡树(树套树:线段树+Treap)

描述 可以处理区间问题的平衡树. 分析 树套树.可以用线段树套Treap.人生第一道树套树的题... op1:如果在整区间,直接在该区间的treap上求解.否则分两个区间求解,然后相加.最后+1. op2:这个不太好直接做,可以二分,每次假定一个值,用这个值去做op1,以此求得一个rank=k+1的数,求rank=k的数等价与求这个数的前驱pre. op3:先删后加. op4&op5:如果在整区间,直接在该区间的treap上求解,否则分量个区间求解,pre取最大值,suc取最小值.注意有些数在有

BZOJ 3110: [Zjoi2013]K大数查询 [树套树]

3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6050  Solved: 2007[Submit][Status][Discuss] Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. Input 第一行N,M接下来M行,每行形如1 a

[POJ] #1003# 487-3279 : 桶排序/字典树(Trie树)/快速排序

一. 题目 487-3279 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 274040   Accepted: 48891 Description Businesses like to have memorable telephone numbers. One way to make a telephone number memorable is to have it spell a memorable word or

[BZOJ3110] [Zjoi2013] K大数查询 (树套树)

Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. Input 第一行N,M 接下来M行,每行形如1 a b c或2 a b c Output 输出每个询问的结果 Sample Input 2 5 1 1 2 1 1 1 2 2 2 1 1 2 2 1 1 1 2 1 2 3 Sample Output 1 2 1 HINT [

bzoj 3295: [Cqoi2011]动态逆序对(树套树 or CDQ分治)

Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数. Input 输入第一行包含两个整数n和m,即初始元素的个数和删除的元素个数.以下n行每行包含一个1到n之间的正整数,即初始排列.以下m行每行一个正整数,依次为每次删除的元素. Output 输出包含m行,依次为删除每个元素之前,逆序对的个数. Sample Input 5 4 1 5 3

树状树组(Binary Indexed Tree (BIT))的C++部分实现

一.树状数组的用处 树状树组是将一个线性数组保存为“树状”,当修改某点的值.求某个区间的和的时候能够有效的减少时间复杂度.当数组长度为N,实时对数组进行M次修改或求和,最坏的情况下复杂度是O(M*N). 二.树状数组的建立 假设输入数组为 vector<int> nums 将其转化为树状数组的本质在于将数组的原先顺序打乱后,经过特殊的求和方法,组合成新的数组,代码如下.关键点在于k+=k&-k,这是一个利用二进制码的特点完成树状数组下标的选取. 1 size = nums.size()

BZOJ3295 动态逆序对 树套树, 树状数组套线段树(主席树)

Orz黄学长,蒟蒻在黄学长的带领下,通过阅读黄学长的代码!终于会了这道题! 首先我想先说一下这道题的思路(准确来说是黄学长的). 很明显,树状数组应该不用讲吧!关键是内存怎么开,维护一些什么样的数据? 其实我们通过观察,很快可以发现,你维护被删的数比维护所有的数轻松多了(不管是空间上,还是时间上).所以我们就可以从这方面想!(其实我一开始的思路,因为这道题我已经看过很久了,一直想写,毕竟是白书里面的一道例题嘛!一开始,蒟蒻的我是打算这样的用树状数组套权值线段树,并且是维护所有的数,我发现空间不够

归并树 划分树 可持久化线段树(主席树) 入门题 hdu 2665

如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k大 ,,,, 这个问题的通用算法是 划分树,, 说白一点就是把快速排序的中间结果存起来, 举个栗子 原数列 4 1 8 2 6 9 5 3 7 sorted 1 2 3 4 5 6 7 8 9 ........................... qs[0] 4 1 8 2 6 9 5 3 7 q

bzoj3110: [Zjoi2013]K大数查询 【树套树,标记永久化】

好久没写题解了. 但是这题太神了然后做法太神了于是写一下. 这题做法很多,比如黄学长hzw的权值线段树套线段树,比如学长云的bit套主席树(其实是写法更神然后我不会用). 然后看到hzhwcmhf大神题解. http://tieba.baidu.com/p/2246783535 震惊了. 好了开说说做法.建一颗朴素的线段树,树的每个点表示每个区间,然后每个区间建两棵树,一棵是mark树,一棵是all树,两棵都是权值线段树. “mark表示该区间每个点上都会加上mark线段树里的元素 all表示该