1.基本概念:

M定义为树的高度,也叫阶,就是树的深度;

(1).B树又称为多路平衡查找树。

(2).根节点至少有两个子节点。

(3).除根节点以外的非叶子节点的儿子树为[M/2,M]。

(4).每个节点存放至少M/2 - 1 (向上取整) 和 至多 M-1个关键字。

(5).非叶子节点的关键字个数 = 指向儿子的指针个数 - 1。

(6).非叶子节点的关键字: K[1], K[2],...,K[M-1]; 且 K[i] < K[i + 1]。

(7).非叶子节点的指针 : P[1],P[2],....P[M],其中P[1]指向关键字小于K[1]

P[M]指向关键字及其子树的值大于K[M-1]的值 。

(8).所有叶子节点位于同一层。

2.B-树的查找:

B-树的查找过程:根据给定值查找节点和在节点的关键字中进行查找交叉进行。首先从根节点开始重复如下过程:

若比节点的第一个关键字小,则查找在该节点第一个指针指向的节点进行,若等于节点中某个关键字,则查找成功;若在两个关键字之间,则查找在他们之间的指针指向的节点进行;若比该节点所有的关键字打,则查找在该节点最后一个指针指向的节点进行;若查找已经到达某个叶子节点,则说明给定值对应的数据记录不存在,查找失败。

3.B-树的插入:

插入的过程分两步完成;

(1)利用前面的B-树的查找算法查找关键字的插入位置,若找到,则说明该关键字已经存在,直接返回。

(2)判断该节点是否还有空位置,即判断该节点的关键字总数是否小于M-1。若满足,则说明该节点还有空位置,直接把关键字K插入到该节点的合适位置上,若不满足,说明该节点已经没有空位置,需要把节点分成两个。

分裂的方法是:生成一个新节点。把原来节点上的关键字和K按照升序排序后,从中间位置把关键字分成两部分。左部分所含关键字放在旧节点中,右部分所含关键字放在新节点中,中间位置的关键字连同新节点的存储位置插入到父节点中。如果父节点的关键字个数也超过M-1则要再进行分裂,再往上插。直至这个过程传到根节点为止。

4.B_树的删除

在B-树上删除关键字K的过程分两步完成:

(1)利用前面的B-树的查找算法找出改关键字所在的节点。然后根据K所在节点是否为叶子节点有不同的处理方法;

(2)若该节点为非叶子节点,且被删除关键字为该节点中的第i个关键字key[i],则可从指针son[i]所指的子树中找出最小关键字Y,代替key[i]的位置,然后再叶子节点中删除Y。

因此,把在非叶子节点删除关键字K的问题就变成了删除叶子节点中的关键字问题了。

在B-树叶子节点上删除一个关键字的方法是

  首先将要删除的关键字K直接从该叶子节点中删除。然后根据不同情况分别作相应的处理,共有三种可能情况:

(1)如果被删除关键字所在节点的原关键字个数n>=ceil(m/2),说明删除该关键字后该节点仍然满足B-树的蒂尼。这种情况最简单。

(2)如果被删除关键字所在节点的关键字个数n等于ceil(m/2) -1,说明删除该关键字后该节点不满足B-树的定义,需要调整。

  调整的过程:如果其左右兄弟节点中右“多余”的关键字,即与该节点相邻的右(左)兄弟节点中的关键字数目大于ceil(m/2)-1。则可将右(左)兄弟节点中最小(大)关键字上移至双亲节点。而将双亲节点中小(大)于该上移关键字的关键字下移至被删关键字所在节点中。

(3)如果左右兄弟节点中没有“多余”的关键字,即与该节点相邻的右(左)兄弟节点中的关键字数目均等于ceil(m/2) - 1。这种情况比较复杂,需要把要删除关键字的节点与其左(或右)兄弟节点以及双亲节点中分割二者的关键字合并成一个节点,即在删除关键字后,该节点中剩余的关键字加指针,加上双亲节点中的关键字Ki一起,合并到Ai(是双亲节点指向该删除关键字节点的左(右)兄弟节点的指针)所指的兄弟节点中去。如果因此使双亲节点中关键字个数小于ceil(m/2) -1,则对此双亲节点做同样处理。以致于可能直到对根节点做这样的处理而使整个树减少一层。

总之,设所删关键字为非叶子节点中的Ki,则可以指针Ai所指子树中的最小关键字Y代替Ki,然后再相应节点中删除Y。对任意关键字的删除都可以转换为对最下层关键字的删除。

参考文献:http://www.cnblogs.com/oldhorse/archive/2009/11/16/1604009.html

     https://wenku.baidu.com/view/387c4d6c5727a5e9856a6186.html

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

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

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6050  Solved: 2007[Submit][Sta ...

  2. 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 ...

  3. Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结

    Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 ...

  4. bzoj3262: 陌上花开(树套树)

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  5. bzoj3295: [Cqoi2011]动态逆序对(树套树)

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  6. BZOJ 3110 k大数查询 & 树套树

    题意: 有n个位置,每个位置可以看做一个集合,现在要求你实现一个数据结构支持以下功能: 1:在a-b的集合中插入一个数 2:询问a-b集合中所有元素的第k大. SOL: 调得火大! 李建说数据结构题能 ...

  7. HDU 5877 dfs+ 线段树(或+树状树组)

    1.HDU 5877  Weak Pair 2.总结:有多种做法,这里写了dfs+线段树(或+树状树组),还可用主席树或平衡树,但还不会这两个 3.思路:利用dfs遍历子节点,同时对于每个子节点au, ...

  8. BZOJ 3110 树套树 && 永久化标记

    感觉树套树是个非常高深的数据结构.从来没写过 #include <iostream> #include <cstdio> #include <algorithm> ...

  9. 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组

    涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...

  10. 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))

    函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...

随机推荐

  1. %ROWTYPE在INSERT和UPDATE语句里的妙用

    PL/SQL里的ROWTYPE类型具有非常大的用处和灵活性,现在发现ROWTYPE在insert和update语句里的妙用,可以节省很多代码,特别是在行copy和更新的时候. 在INSERT语句中: ...

  2. 【TOJ 3305】Hero In Maze II

    描述 500年前,Jesse是我国最卓越的剑客.他英俊潇洒,而且机智过人^_^.突然有一天,Jesse心爱的公主被魔王困在了一个巨大的迷宫中.Jesse听说这个消息已经是两天以后了,他急忙赶到迷宫,开 ...

  3. 【模板】全排列(运用STL的next_permutation)

    (1) 先将要排列的数据存入数组中: (2) 再将数组元素从小到大排序: (3) 每次调用next_permutation函数,都只进行1次排列,若数组元素完全变为递减的排列,则该函数返回0: int ...

  4. Linux下NFS服务器的搭建与配置(转载)

    一.NFS服务简介 NFS 就是 Network FileSystem 的缩写,最早之前是由sun 这家公司所发展出来的. 它最大的功能就是可以透过网络,让不同的机器.不同的操作系统.可以彼此分享个别 ...

  5. MySQL数据表操作(DDL)

    一.创建数据表 语法:create table 表名称(字段 字段类型 [字段属性],字段 字段类型 [字段属性],...) [表选项]; 表选项:数据表的属性,一般包括engine.charset. ...

  6. Java源码解析——集合框架(四)——LinkedListLinkedList原码分析

    LinkedList源码分析 LinkedList也和ArrayList一样实现了List接口,但是它执行插入和删除操作时比ArrayList更加高效,因为它是基于链表的.基于链表也决定了它在随机访问 ...

  7. Laravel 5.5搭建(lunix-ubuntu)

    基本配置 PHP >= 7.0.0 PHP OpenSSL 扩展 PHP PDO 扩展 PHP Tokenizer 扩展 PHP XML 扩展 1:nginx sudo apt-get upda ...

  8. Hadoop(9)-HDFS的NameNode和SecondaryNameNode详解

    1.NN和2NN工作机制 首先,我们做个假设,如果存储在NameNode节点的磁盘中,因为经常需要进行随机访问,还有响应客户请求,必然是效率过低.因此,元数据需要存放在内存中.但如果只存在内存中,一旦 ...

  9. 分布式系统的CAP(Redis)

    CAP理论就是说在分布式存储系统中,最多只能实现上面的两点.而由于当前的网络硬件肯定会出现延迟丢包等问题,所以 分区容忍性是我们必须需要实现的. 所以我们只能在一致性和可用性之间进行权衡,没有NoSQ ...

  10. python2.7入门---SMTP发送邮件

        SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式.python的smtplib提 ...