B树的定义

  假设B树的度为t(t>=2),则B树满足如下要求:(参考算法导论)

(1)  每个非根节点至少包含t-1个关键字,t个指向子节点的指针;至多包含2t-1个关键字,2t个指向子女的指针(叶子节点的子女为空)。

(2)  节点的所有key按非降序存放,假设节点的关键字分别为K[1], K[2] … K[n], 指向子女的指针分别为P[1], P[2]…P[n+1],其中n为节点关键字的个数。则有:

P[1] <= K[1] <= P[2] <= K[2] …..<= K[n] <= P[n+1]   // 这里P[n]也指其指向的关键字

(3)  若根节点非空,则根节点至少包含两个子女;

(4)  所有的叶子节点都在同一层。

B树的搜索,searchroot, target

  从root出发,对每个节点,找到大于或等于target关键字中最小的K[i],如果K[i]与target相等,则查找成功;否则在P[i]中递归搜索target,直到到达叶子节点,如仍未找到则说明关键字不在B树中,查找失败。

B树的插入,insert(root, target)

  B树的插入需要沿着搜索的路径从root一直到叶节点,根据B树的规则,每个节点的关键字个数在[t-1, 2t-1]之间,故当target要加入到某个叶子时,如果该叶子节点已经有2t-1个关键字,则再加入target就违反了B树的定义,这时就需要对该叶子节点进行分裂,将叶子以中间节点为界,分成两个包含t-1个关键字的子节点,同时把中间节点提升到该叶子的父节点中,如果这样使得父节点的关键字个数超过2t-1,则要继续向上分裂,直到根节点,根节点的分裂会使得树加高一层。

上面的过程需要回溯,那么能否从根下降到叶节点后不回溯就能完成节点的插入呢?答案是肯定的,核心思想就是未雨绸缪,在下降的过程中,一旦遇到已满的节点(关键字个数为2t-1),就就对该节点进行分裂,这样就保证在叶子节点需要分裂时,其父节点一定是非满的,从而不需要再向上回溯。

B树的删除,delete(root, target)

  在删除B树节点时,为了避免回溯,当遇到需要合并的节点时就立即执行合并,B树的删除算法如下:从root向叶子节点按照search规律遍历:

(1)  如果target在叶节点x中,则直接从x中删除target,情况(2)和(3)会保证当再叶子节点找到target时,肯定能借节点或合并成功而不会引起父节点的关键字个数少于t-1。

(2)  如果target在分支节点x中:

(a)  如果x的左分支节点y至少包含t个关键字,则找出y的最右的关键字prev,并替换target,并在y中递归删除prev。

(b)  如果x的右分支节点z至少包含t个关键字,则找出z的最左的关键字next,并替换target,并在z中递归删除next。

(c)  否则,如果y和z都只有t-1个关键字,则将targe与z合并到y中,使得y有2t-1个关键字,再从y中递归删除target。

(3)  如果关键字不在分支节点x中,则必然在x的某个分支节点p[i]中,如果p[i]节点只有t-1个关键字。

(a)  如果p[i-1]拥有至少t个关键字,则将x的某个关键字降至p[i]中,将p[i-1]的最大节点上升至x中。

(b)  如果p[i+1]拥有至少t个关键字,则将x个某个关键字降至p[i]中,将p[i+1]的最小关键字上升至x个。

(c)  如果p[i-1]与p[i+1]都拥有t-1个关键字,则将p[i]与其中一个兄弟合并,将x的一个关键字降至合并的节点中,成为中间关键字。

B+

  与B树不同的时,B+树的关键字都存储在叶子节点,分支节点均为索引,在实现上大致与B树类似,在几个细节稍有不同。

(1) 数据结构中增加prev,next指针,用于将叶子节点串成有序双向链表。

(2) 在节点分裂的时候,如果分裂的节点为叶子,则需要把中间节点保留在左(或右)边的分支上,并且需要更新prev和next。

(3) 在节点合的时候,如果合并的节点为叶子,不需要把跟节点下降为中间节点,并且需要更新prev和next。

(4) 在向邻接节点借节点时,借来的关键字并不是父节点的关键字,而是邻接点的关键字,并根据实际情况更新父节点的索引。

源码地址(并且加上了“策略模式”来调用B、B+的方法)我的github上的BTree-and-BPlusTree-Realize项目

B-树、B+树、B*树定义介绍:http://www.cnblogs.com/orange1438/p/4762606.html

作者:orange1438
出处:http://www.cnblogs.com/orange1438/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

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. Gitcafe绑定自定义域名

    之前将自己练习写作工具替换为Markdown,部署工具改为Hexo,并且将托管地搬家到GitCafe之后,便是被各种的舒爽所围绕.具体折腾的详情参见使用Hexo搭建专属Blog.她们的组合方便快捷,让 ...

  2. 负载均衡session会话保持方法

    负载均衡时,为了保证同一用户session会被分配到同一台服务器上,可以使用以下方法:1.使用cookie将用户的session存入cookie里,当用户分配到不同的服务器时,先判断服务器是否存在该用 ...

  3. JS函数 -- 功能,语法,返回值,匿名函数,自调用匿名函数,全局变量与局部变量,arguments的使用

    “JavaScript设计得最出色的就是它的函数的实现.” -- <JavaScript语言精粹> 函数包含一组语句,它们是JS的基础模块单元,用于指定对象的行为.一般来说,所谓编程,就是 ...

  4. 有关binlog的那点事(二)(mysql5.7.13)

    上次,我们仅仅把binlog做了一个概述,并没有去深入探索(1)binlog file究竟是怎么构成的?(2)binlog file的单元binlog events是怎么构成的?(3)我们能不能伪造出 ...

  5. Jquery中的(function($){...})(jQuery)

    当你第一眼看到“(function($){...})(jQuery)”的时候,你有什么感觉?呵呵呵,我当时还是止不住的从心底里骂了一句——操,这他妈什么劳什子.时过境迁,对于现在无比倚重Jquery的 ...

  6. jQuery源码分析系列(30) : Ajax 整体结构

    开头引用一段 想起一句话:前端研究,研究个屁~ 的确如此呀.补充下联:前端设计,设计个屁~ 前端目前最大的困境是,如 HTML 一样,无论你承不承认,市场上并不太需要 HTML 高手 其实这里引发一个 ...

  7. Unity导出的Xcode工程目录

    Classes文件夹: Unity Runtime和ObjectC代码 main.mm和AppController.mm:应用程序入口点 iPhone_Profiler.h:定义了启用内部分析器(In ...

  8. 进程管理三大扩展工具htop

    三大进程管理监控工具 HTOP 介绍: Htop是一款运行于Linux系统监控与进程管理软件,htop提供所有进程的列表,并且使用彩色标识出处理器.swap和内存状态.用户一般可以在top无法提供详尽 ...

  9. Unity Shaders 第一个默认程序分析

    Unity Shaders 第一个默认程序 Shader "Custom/Shader" { Properties { _MainTex ("Base (RGB)&quo ...

  10. 高级javascript---变量作用域

    变量作用域 (JavaScript) JavaScript 有两个范围:全局和局部. 在函数定义之外声明的变量是全局变量,它的值可在整个程序中访问和修改. 在函数定义内声明的变量是局部变量. 每当执行 ...