ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

5、B数、B+数、红黑树

2019-09-30 11:55:12  阅读:337  来源: 互联网

标签:结点 关键码 个子 插入 查找 红黑树 节点


2-3树

关键字 1-2 个
子节点 2-3 个

平衡树:子节点的高度一致

B树(Balacned Tree)

一种平衡的多分树

平衡:所有的叶结点在同一层,所以每个子节点的高度一致

m阶B树的结构定义

1、每个结点至多有m个子结点
2、除根节点和叶节点外,其他每个结点至少有m/2(向上取整)个结点
3、根结点至少有两个子结点

  • 唯一例外的是根节点就是叶结点时没有子结点
  • 此时B树只包含一个结点

4、所有的叶结点在同一层(平衡)
5、有k个子节点的非根节点恰好包含k-1个关键码

B树的性质

1、树高平衡,所有叶结点都在同一层
2、关键码没有重复,父结点中的关键码是其子结点的分界
3、B树把(值接近)相关记录放在同一个磁盘页中,从而利用局部性原理
4、B树保证树中至少有一定比例的结点是满的(每个结点有至少有m/2个子节点,半满)

  • 这样能改进空间的利用率(如果每个节点只有1个子节点,BST,树高会很高,空间利用率低)
  • 减少索引和更新操作的磁盘读取数目(如果每个节点有m个子节点,全满,那么每次插入的时候没处插了)
QM总结:
  • 除根节点和叶节点外,M阶B树每个节点有m/2~m个结点,根节点至少有两个子节点(插入时多次分裂)
  • 有k个子节点的非根节点恰好包含k-1个关键码
  • 父结点中的关键码是其子结点的分界

B树的节点结构

B树的一个包含j个关键码,j+1个指针的节点的一般形式为:

P0,K1,P1,K2,P2....Kj,Pj  #j个关键码,j+1个指针指向子节点

其中ki是关键码值,K1<K2<….<Kj
Pi是指向Ki到Ki+1之间的关键码的子树的指针

QM总结:
  • 如果有j个关键字,那么有可以表示j+1个区间,即有j+1个子节点
  • 关键词下标从1开始,P从0开始,Pi是指向Ki到Ki+1之间的关键码的子树的指针
  • 举个例子:P0指向K0到K1之间,即小于K1的,P1指向K1到K2

B树结点抽象数据类型

class BNode{
    int n;//子节点的个数
    BNode<Key> *parent;//指向父节点的指针(可有可不有)
    Key key[MAXREC];//存储关键码的数组,最多有MAXREC个关键码
    BNode<Key> *ptr[MAXREC+1];//指向子节点的指针,最多有MAXREC+1个指针
}

B树的查找

1、把根节点读出来,在根节点所包含的关键码K1…Kj中查找给定的关键码值。当关键码不多时,就用顺序检索,当节点包含的关键码较多时,可以用二分检索。如果找到则检索成功

2、否则,确定要查的关键码指在某个Ki和Ki+1之间,那么去Pi所指向的节点继续查找

下图为查找24的过程

如果树高为h,则查找时访问外存的次数是h

注意:
每个关键码表示索引,找到索引后,每个关键码还对应一个指向外存的指针,这样通过索引才可以访问到完整的记录

B树的插入(分裂向上生长)

情况1:

首先判断关键码14是否存在,按照图中的轨迹查找,此时到15所在的节点,遍历后发现没有14,则在该节点中插入

此时外存读的次数是3,写的次数是1

情况2:

插入可能导致B树朝着根的方向生长,即当插入位置超过关键字的最大个数,节点需要进行分裂

如插入55,但2-3树要求关键字数只由1~2个,此时插入节点50,52已经达到个数,55无法直接插入,需要进行分裂

50 52 55如何拆分?

父节点需要增加一个节点进行区分子节点拆分后的节点,采用二分的方法,将中间的52送到父节点,得到结果:

此时读的次数3,写的次数3(申请两个节点,并分别写入,这里包含两次写,还有在父节点中写入1次)

情况3:

多次分裂,树向上生长

最终的结果是:

B数的删除(向左或向右合并)

6阶B树删除45

对于6阶B树,子节点树要求m/2~m,即 3~6,关键码的个数为2~5,在删除的过程中需要防止下溢出,即关键码的数量小于规定的个数

在删除掉45后,当前节点只有110一个关键字,下溢出了。其中一种方案是向左右节点借关键码,同时要将父节点拉下来,这里演示向右节点借关键码。此时合并的关键码有110,112,135,143,212,需要进行分裂,根据二分分裂的方式,将135移到父节点,即用135替换123,然后子节点分裂,反别是110,112和142,212,结果是:

给出一个极限情况下删除的例子:

删除的时候如果发生下溢出,即当前关键码个数小于定义的个数,则需要进行合并,向左节点或有节点合并

如果删除后,节点为0仍保持0的状态,按照向左向右合并的方式进行操作

B+树

B+树是B树的一种变形,是在叶结点上存储信息的树

  • 所有的管家那么均出现在叶结点上
  • 各层节点中的关键码均是下一层相应节点中最大关键码(或最小关键码)的复写

B+树的结构定义

  • 每个节点至多有m个子节点
  • 每个结点(除根外)至少有m/2(向上取整)个子结点
  • 根节点至少有两个子结点
  • 有k个子结点的必有k个关键码(这个是与B树的差别)
QM总结:
  • 根节点有2~m个子节点
  • 除根节点外有m/2(向上取整)~m个子结点
  • 有k个子结点的节点有k个关键字(这是与B树的结构差别,B树有k-1个关键字)

  • m阶B+树有m个子节点,也有m个关键字
  • m个关键字是子结点的复写,当前层的关键码是其每个子结点关键码的最大关键码(也可以是最小)
  • 根节点是线性索引,可以顺序查找;再加上多分树形查找
  • 树形索引中不包含指向真实数据位置的指针,必须索引到树的叶子节点才算找到;好处是可以提高树的阶数,降低树的高度,加速索引速度

B+树的插入

如下3阶B+树,节点最多有3个关键码,当插入15后,查询到10 23这个节点,插入15。父节点不需要重写

3阶B+树插入16后,叶子节点的关键为16超过最大阶3,所以需要分类成10、15和16、23,并增加分类节点之间的线性链接,修改父节点的关键码,每个关键码是子结点关键码最大值的复写

多次分裂

B+树的删除

如下B+树删除23,首先需要查找23;第一个节点判断,23<=35,到第二个子结点查找;23<=23,在第一个子结点中查找;删除关键码23;

此时父节点中的23能够正确标识父节点的区间,所以不进行更新(类似线段树中的延迟更新)

B树与B+树的区别

节点结构:

  • 当前节点有k个子结点,B树有k-1个关键码,B+树有k个关键码
  • B树当前节点的关键码类似BST是子结点关键码的分割,B+树当前节点的关键码是子结点的复写(子结点关键码的最大值或最小值)

查找:

B树每个节点保存了指向真实位置的指针,找到关键码就能找到真实位置;B+树必须索引到叶子节点;B+树提供了索性查找和顺序查找两种方式

实际中使用B+树特别多

参考

第10章 索引——2(B树,B树) 标清
https://www.youtube.com/watch?v=vBD6Ve8VryY

原文:大专栏  5、B数、B+数、红黑树


标签:结点,关键码,个子,插入,查找,红黑树,节点
来源: https://www.cnblogs.com/chinatrump/p/11611922.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有