B树

即二叉搜索树:

1.所有非叶子结点至多拥有两个儿子(Left和Right);

2.所有结点存储一个关键字;

3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树;

如:

B树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中;

否则,如果查询关键字比结点关键字小,就进入左儿子;如果比结点关键字大,就进入

右儿子;如果左儿子或右儿子的指针为空,则报告找不到相应的关键字;

如果B树的所有非叶子结点的左右子树的结点数目均保持差不多(平衡),那么B树

的搜索性能逼近二分查找;但它比连续内存空间的二分查找的优点是,改变B树结构

(插入与删除结点)不需要移动大段的内存数据,甚至通常是常数开销;

如:

但B树在经过多次插入与删除后,有可能导致不同的结构:

右边也是一个B树,但它的搜索性能已经是线性的了;同样的关键字集合有可能导致不同的

树结构索引;所以,使用B树还要考虑尽可能让B树保持左图的结构,和避免右图的结构,也就

是所谓的“平衡”问题;

实际使用的B树都是在原B树的基础上加上平衡算法,即“平衡二叉树”;如何保持B树

结点分布均匀的平衡算法是平衡二叉树的关键;平衡算法是一种在B树中插入和删除结点的

策略;

B-树

是一种多路搜索树(并不是二叉的):

1.定义任意非叶子结点最多只有M个儿子;且M>2;

2.根结点的儿子数为[2, M];

3.除根结点以外的非叶子结点的儿子数为[M/2, M];

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

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]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;

8.所有叶子结点位于同一层;

如:(M=3)

B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果

命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为

空,或已经是叶子结点;

B-树的特性:

1.关键字集合分布在整颗树中;

2.任何一个关键字出现且只出现在一个结点中;

3.搜索有可能在非叶子结点结束;

4.其搜索性能等价于在关键字全集内做一次二分查找;

5.自动层次控制;

由于限制了除根结点以外的非叶子结点,至少含有M/2个儿子,确保了结点的至少

利用率,其最底搜索性能为:

其中,M为设定的非叶子结点最多子树个数,N为关键字总数;

所以B-树的性能总是等价于二分查找(与M值无关),也就没有B树平衡的问题;

由于M/2的限制,在插入结点时,如果结点已满,需要将结点分裂为两个各占

M/2的结点;删除结点时,需将两个不足M/2的兄弟结点合并;

B+树

B+树是B-树的变体,也是一种多路搜索树:

1.其定义基本与B-树同,除了:

2.非叶子结点的子树指针与关键字个数相同;

3.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树

(B-树是开区间);

5.为所有叶子结点增加一个链指针;

6.所有关键字都在叶子结点出现;

如:(M=3)

B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在

非叶子结点命中),其性能也等价于在关键字全集做一次二分查找;

B+的特性:

1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好

是有序的;

2.不可能在非叶子结点命中;

3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储

(关键字)数据的数据层;

4.更适合文件索引系统;

B*树

是B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针;

B*树定义了非叶子结点关键字个数至少为(2/3)*M,即块的最低使用率为2/3

(代替B+树的1/2);

B+树的分裂:当一个结点满时,分配一个新的结点,并将原结点中1/2的数据

复制到新结点,最后在父结点中增加新结点的指针;B+树的分裂只影响原结点和父

结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针;

B*树的分裂:当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分

数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字

(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之

间增加新结点,并各复制1/3的数据到新结点,最后在父结点增加新结点的指针;

所以,B*树分配新结点的概率比B+树要低,空间使用率更高;

小结

B树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于

走右结点;

B-树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键

字范围的子结点;

所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;

B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点

中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;

B*树:在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率

从1/2提高到2/3;

数据结构B树的更多相关文章

  1. python数据结构之树和二叉树(先序遍历、中序遍历和后序遍历)

    python数据结构之树和二叉树(先序遍历.中序遍历和后序遍历) 树 树是\(n\)(\(n\ge 0\))个结点的有限集.在任意一棵非空树中,有且只有一个根结点. 二叉树是有限个元素的集合,该集合或 ...

  2. 学习javascript数据结构(四)——树

    前言 总括: 本文讲解了数据结构中的[树]的概念,尽可能通俗易懂的解释树这种数据结构的概念,使用javascript实现了树,如有纰漏,欢迎批评指正. 原文博客地址:学习javascript数据结构( ...

  3. [翻译]Linux 内核里的数据结构 —— 基数树

    目录 Linux 内核里的数据结构 -- 基数树 基数树 Radix tree Linux内核基数树API 链接 Linux 内核里的数据结构 -- 基数树 基数树 Radix tree 正如你所知道 ...

  4. 算法手记 之 数据结构(线段树详解)(POJ 3468)

    依然延续第一篇读书笔记,这一篇是基于<ACM/ICPC 算法训练教程>上关于线段树的讲解的总结和修改(这本书在线段树这里Error非常多),但是总体来说这本书关于具体算法的讲解和案例都是不 ...

  5. Java数据结构之树和二叉树(2)

    从这里始将要继续进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来 ...

  6. Java数据结构之树和二叉树

    从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...

  7. [数据结构]字典树(Tire树)

    概述: Trie是个简单但实用的数据结构,是一种树形结构,是一种哈希树的变种,相邻节点间的边代表一个字符,这样树的每条分支代表一则子串,而树的叶节点则代表完整的字符串.和普通树不同的地方是,相同的字符 ...

  8. 数据结构(主席树):COGS 2211. 谈笑风生

    2211. 谈笑风生 ★★★★   输入文件:laugh.in   输出文件:laugh.out   简单对比时间限制:3 s   内存限制:512 MB [问题描述] 设T 为一棵有根树,我们做如下 ...

  9. 数据结构-B树

      1.前言: 动态查找树主要有:二叉查找树(Binary Search Tree),平衡二叉查找树(Balanced Binary Search Tree),红黑树(Red-Black Tree ) ...

  10. 数据结构之树(Tree)(一) :树

    ps:好久没用动手写blog了,要在这条路上不断发展,就需要不停的学习,不停的思考与总结,当把写blog作为一种习惯,就是自我成长的证明,Fighting!. 一.简介 树是一种重要的非线性数据结构, ...

随机推荐

  1. Linux中变量#,#,@,0,0,1,2,2,*,$$,$?的含义【转】

    转自:http://www.cnblogs.com/kaituorensheng/p/4002697.html 1 2 3 4 5 6 7 8 $# 是传给脚本的参数个数 $0 是脚本本身的名字 $1 ...

  2. Multi-source Replication

    MariaDB starting with 10.0.1 Multi-source replication means that one server has many masters from wh ...

  3. Hibernate,JPA注解@DynamicInsert和@DynamicUpdate,Hibernate如何插入sysdate

    @DynamicInsert属性:设置为true,设置为true,表示insert对象的时候,生成动态的insert语句,如果这个字段的值是null就不会加入到insert语句当中.默认false. ...

  4. C#:关联程序和文件

    一.关联代码 /// <summary> /// 关联程序和类型 /// </summary> private void RegFileExt() { try { string ...

  5. 超文本标记语言(HTML)

    超文本标记语言(HyperText MarkUp Language,HTML) HTML是用来制作网页的标记语言,HTML不需要编译,直接由浏览器解析: HTML文件是一个文本文件,包含了一些HTML ...

  6. [ios][opengles]OpenGL ES基础知识简介

    参考: http://www.cnblogs.com/shangdahao/archive/2011/11/05/2233587.html 3D变换:模型,视图,投影与Viewport: http:/ ...

  7. 手把手教你用C++ 写ACM自动刷题神器(冲入HDU首页)

    转载注明原地址:http://blog.csdn.net/nk_test/article/details/49497017 少年,作为苦练ACM,通宵刷题的你 是不是想着有一天能够荣登各大OJ榜首,俯 ...

  8. C#之参数线程

    public Form1() { InitializeComponent(); } Thread t; private void button1_Click(object sender, EventA ...

  9. 20150604_Andriod 窗体PopupWindow动画

    参考地址: http://www.open-open.com/lib/view/open1378720752084.html http://www.jcodecraeer.com/a/anzhuoka ...

  10. Uva 1347,旅行

    题目链接:https://uva.onlinejudge.org/external/13/1347.pdf 这个题和uva 1658题目很像,只是加了一点,就是每个点都要走,刚开始,我以为可以直接拆点 ...