[数据结构]查找(三)

第九章 查找

9.2  动态查找表

三、B - 树

1.B-树的定义

B-树是一种 平衡 的 多路 查找 树:

 

多叉树的特性

   在 m 阶的B-树上,每个非终端结点可能含有:

  · n 个关键字 Ki(1≤ i≤n) n<m

  · n 个指向记录的指针 Di(1≤i≤n)

  · n+1 个指向子树的指针 Ai(0≤i≤n)

B-树结构的C语言描述如下:

typedef struct BTNode {

  int  keynum;        // 结点中关键字个数,结点大小

  struct BTNode  *parent;  

                            // 指向双亲结点的指针

  KeyType   key[m+1]; // 关键字(0号单元不用)

  struct BTNode  *ptr[m+1]; // 子树指针向量

  Record        *recptr[m+1];  // 记录指针向量

} BTNode, *BTree; // B树结点和B树的类型

查找树的特性

· 非叶结点中的多个关键字均自小至大有序排列,即:K1< K2 < … < Kn  ;

· Ai-1 所指子树上所有关键字均小于Ki  ;

· Ai 所指子树上所有关键字均大于Ki  ;

平衡树的特性

· 树中所有结点均不带信息,且在树中的同一层次上;

· 若根结点不是叶子结点,则至少含有两棵子树;

· 其余所有含有非叶结点均至少含有[m/2]棵子树,至多含有m棵子树。

2.查找过程:

  从根结点出发,沿指针搜索结点和在结点内进行顺序(或折半)查找 两个过程交叉进行。

  若查找成功,则返回指向被查关键字所在结点的指针和关键字在结点中的位置;若查找不成功,则返回插入位置。

假设返回的是如下所述结构的记录:

typedef struct {

  BTNode  *pt;     // 指向找到的结点的指针

  int  i;       // 1..m,在结点中的关键字序号

  int  tag;   // 标志查找成功(=1)或失败(=0)

} Result;             // 在B树的查找结果类型

Result SearchBTree(BTree T, KeyType K) {

  // 在m 阶的B-树 T 中查找关键字 K, 返回

  // 查找结果 (pt, i, tag)。若查找成功,则

  // 特征值 tag=1, 指针 pt 所指结点中第 i 个

  // 关键字等于 K; 否则特征值 tag=0, 等于

  //  K 的关键字应插入在指针 pt 所指结点

  // 中第 i 个关键字和第 i+1个关键字之间

 

} // SearchBTree

p=T;  q=NULL;  found=FALSE;  i=0;

 while (p && !found) {

    n=p->keynum;   i=Search(p, K);  

    // 在p->key[1..keynum]中查找 i ,  p->key[i]<=K<p->key[i+1]

    if (i>0 && p->key[i]==K)  found=TRUE;

    else { q=p;   p=p->ptr[i]; }  // q 指示 p 的双亲

 }

 if (found)  return (p,i,1);       // 查找成功

 else return (q,i,0);              // 查找不成功

3.插入

在查找不成功之后,需进行插入。显然,关键字插入的位置必定在最下层的非叶结点,有下列几种情况:

1)插入后,该结点的关键字个数n<m, 不修改指针;

2)插入后,该结点的关键字个数 n=m,则需进行“结点分裂”,令 s = [m/2],在原结点中保留(A0,K1,……  , Ks-1,As-1);建新结点(As,Ks+1,……  ,Kn,An);将(Ks,p)插入双亲结点;

3)若双亲为空,则建新的根结点。

例如:下列为 3 阶B-树

 

插入关键字 = 60, 90,30,

4.删除

    和插入的考虑相反,首先必须找到待删关键字所在结点,并且要求删除之后,结点中关键字的个数不能小于ém/2ù-1,否则,要从其左(或右)兄弟结点“借调”关键字,若其左和右兄弟结点均无关键字可借(结点中只有最少量的关键字),则必须进行结点的“合并”。有下列三种可能

1.被删关键字所在结点中的关键字数目不小于[m/2],则只需从该结点中删去该关键字Ki和相应指针Ai,树的其它部分不变。

 

删除关键字 = 12

2.被删关键字所在结点中的关键字数目等于ém/2ù-1,而与该结点相邻的右兄弟(或左兄弟)结点中的关键字数目大于ém/2ù-1,则需将其兄弟结点中的最小(或最大)关键字上移至双亲结点中,而将双亲结点中小于(或大于)且紧靠该上移关键字的关键字下移至被删结点中。

 

删除关键字 = 50

3.被删关键字所在结点和其相邻的兄弟结点中的关键字数目均等于ém/2ù-1,假设该结点有兄弟结点,且其右兄弟结点地址由双亲结点中的Ai所指,则在删去关键字之后,它所在结点中剩余的关键字和指针,加上双亲结点中的关键字Ki,合并到Ai所指兄弟结点中(若没有右兄弟,则合并至左兄弟结点中)。

 

删除关键字 = 53

5.查找性能的分析

在B-树中进行查找时,其查找时间主要花费在搜索结点(访问外存)上,即主要取决于B-树的深度。

问:含 N 个关键字的 m 阶 B-树可能达到的最大深度 H 为多少?

反过来问: 深度为H的B-树中,至少含有多少个结点?

先推导每一层所含最少结点数:

第 1 层            1 个

第 2 层            2 个

第 3 层            2*[m/2]个

第 4 层            2*([m/2])2 个

…   …

第 H+1 层          2*([m/2]) H-1 个

结论:

在含 N 个关键字的 B-树上进行一次查找,需访问的结点个数不超过

 

四、B+树

1.B+树的结构特点:

※ 每个叶子结点中含有 n 个关键字和  n 个指向记录的指针;并且,所有叶子结点彼此相链接构成一个有序链表,其头指针指向含最小关键字的结点;

※ 每个非叶结点中的关键字 Ki 即为其相应指针 Ai 所指子树中关键字的最大值;

※ 所有叶子结点都处在同一层次上,每个叶子结点中关键字的个数均介于 ém/2ù和 m 之间。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值