B树知识点总结

B树的性质

1.每个结点x有下面属性:

x.n,当前存储在结点x中的关键字个数。

x.n个关键字按非降序排列。

x.leaf,一个布尔值,如果x是叶结点,则为TRUE;如果x为内部结点,则为FALSE。

2.每个内部结点x有x.n+1个指向其孩子的指针,叶结点是没有孩子的。

3.和二叉搜索树和红黑树一样,也是左小右大。

4.每个叶结点具有相同的深度,即树的高度h。

5.每个结点所包含的关键字个数有上界和下界。用整数t(B树的最小度数)来表示这些界。除了根结点以外的每个结点必须至少有t-1个关键字。因也就意味着除了根结点以外的每个内部结点至少有t个孩子。如果树非空,根结点至少有一个关键字;每个结点至多有2t-1个关键字。因此,一个内部结点至多有2t个孩子。

B树上的基本操作

搜索B树

 

B-TREE-SEARCH(x,k)
  i=1
  while i<=x.n and k>x.key(i)
    i=i+1
  if i<=x.n and k==x.key(i)
    return(x.i)
  else if x.leaf
    return NIL  //x已经是叶子结点,但还没找到,说明不存在
  else DISK-READ(x,c(i))
    return B-TREE-SEARCH(X.(i),k)  递归到子树去寻找

向B树中插入一个关键字

分裂B树中的结点

1.如果树的内部结点x是非满的,也就是x.n<2t-1。而x.c(i)(也就是某个孩子结点)是满节点,意味着x.c(i).n=2t-1。该过程就是将这个满节点分裂成两个,然后将中间元素调整到x中。

2.如果是一个满根结点,要想分裂的话,先创建一个新的结点使之成为根结点,然后再按照1的步骤进行。

 

B-TREE-SPLIT-CHILD(x,i)
  z=ALLOCATE-NODE()  //分配一个新节点
  y=x.c(i)  //y是x的孩子,也是待分裂的结点
  z.leaf=y.leaf  //若y为叶子结点,则z也是,若y不是叶子结点,z也不是
  z.n=t-1  //新节点z的关键字个数
  for j=1 to t-1
    z.key(i)=y.key(j+t)  //z的关键字为y的关键字的后t-1个,也就是y结点中下标为j+1至2t-1的关键字
  if not y.leaf
    for j=1 to t
      z.c(j)=y.c(j+t)  //若y不是叶子结点,则将y的从t+1开始的孩子结点变成z的孩子结点
  y.n=t-1  
  for j=x.n+1 downto i+1
    x.c(j+1)=x.c(j)  //把x的孩子从i+1开始集体后移一位
  x.c(j+1)=z  //将z赋予x的孩子结点
  for j=x.n downto i  
    x.key(j+1)=x.key(i)  //把x的关键字从i开始集体后移一位
  x.key(i)=y.key(i)  //把y的中间关键字插到x中
  x.n=x.n+1  //x的关键字个数加一
  DISK-WRITE(y)
  DISK-WRITE(z)
  DISK-WRITE(x)

向一棵B树中插入关键字

 

《B树知识点总结》

向B树中插入关键字F,这就是属于要分裂结点的情况,也是最复杂的情况

《B树知识点总结》

 

B-TREE-INSERT(T,k)
  r=T.root
  if r.n==2t-1  //如果根结点满了,进行特殊处理
    s=ALLOCATE-NODE()  //分配一个新的结点作为根,所以说对根进行分裂是增加B树高度的唯一途径
    T.root=s
    s.leaf=FALSE
    s.n=0
    s.c(1)=r  //以r为根的子树是第一个孩子
    B-TREE-SPLIT-CHILD(s,1)  //利用分裂结点的情况处理
    B-TREE-INSERT-NONFULL(s,k)
  else
    B-TREE-INSERT-NONFULL(r,k)

 

B-TREE-INSERT-NONFULL(x,k)  // 新插入的关键字肯定发生在叶子结点上
  i=x.n
  if x.leaf  //如果x是叶子结点,则在x结点中找寻要插入的位置
    while i>=1 and k<x.key(i)  //找比新插入的关键字大的关键字
      x.key(i+1)=x.key(i)
      i=i-1
    x.key(i+1)=k
    x.n=x.n+1
    DISK-WRITE(x)
  else  //如果x不是叶子结点,从合适的孩子结点里面去找
    while i>=1 and k<x.key(i)
      i=i-1
    i=i+1  //合适的孩子结点下标
    DISK-WRITE(x.c(i))  
    if x.c(i).n==2t-1  //如果孩子结点是满节点,进行分裂处理
      B-TREE-SPLIT-CHILD(x,i)
      if k>x.key(i)  
        i=i+1  //如果做了分裂处理,这是新的孩子结点下标
    B-TREE-INSERT-NONFULL(x.c(i),k)  //递归处理

 

 

 

 

 

 

    原文作者:B树
    原文地址: https://blog.csdn.net/wk_bjut_edu_cn/article/details/79604890
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞