算法导论的课要完成一个小课题,选了B树,花了挺长时间弄完,之前写了几个简单的排序,发现这递归是真的牛批啊。代码部分参考了这位博主。在写前面的插入那一大块,书上有伪代码可以对着写。但是后面的删除部分没有伪代码,懵了好久,找到另一位博主写的伪代码,有几处小错误,我重新写了一遍,并加上了注释(自己理解的注释,可能有地方理解有误)。不多bb,直接上伪代码和最终源码
// 伪代码均以书上的标准对照着写的,下标均以1开始
// x表示父结点,i表示x中要向下合并的关键字下标
// 并且这里还必须保证父结点关键字个数至少是t个(当然根结点除外),左右两个子结点的关键字个数是t-1
B-TREE-MERGE-CHILD(x,i)
1 y=x.ci //获取左子结点
2 z=x.ci+1 //获取右子结点
3 y.n=2t-1 // 设置左子结点的关键字个数为最大个数
4 y.keyt=x.keyi // 转移父结点要合并的关键字
5 for j=t+1to 2t-1 // 注意下标,转移关键字个数是t-1个
6 y.keyj=z.keyj-t // 转移右子结点的关键字
7 if noty.leaf
8 for j=t+1 to 2t // 孩子结点指针个数是t个
9 y.cj=z.cj-t
10 for j=i+1 to x.n // 父结点在i之后的、孩子结点指针都要前移
11 x.keyj-1=x.keyj // 关键字前移一位
12 x.cj=x.cj+1 // 孩子结点指针前移一位
13 x.n=x.n-1 //最后要将父结点的关键字个数减一
14 FREE-NODE(z)
15 DISK-WRITE(x)
16 DISK-WRITE(y)
//这里对根结点关键字只有1个,并且两个子结点关键字个数都是t-1,进行特殊处理
B-TREE-DELETE(T,k)
1 r=T.root
2 ifr.n==1
3 DISK-READ(x,c1)
4 DISK-READ(x,c2)
5 y=r.c1
6 z=r.c2
7 if y.n==z.n==t-1 // case 2c or 3b其实为什么2c也是这种情况,我也弄不明白,书上写的“可能出现”
8 B-TREE-MERGE-CHILD(r,1)
9 T.root=y
10 FREE-NODE(r)
11 B-TREE-DELETE-NONONE(y,k)
12 elseB-TREE-DELETE-NONONE(r,k)
13 else B-TREE-DELETE-NONONE(r,k)
// NONONE,以我的理解就是非上面的DELETE中处理的特殊情况。即根结点关键字只有1个,并且两个子结点关键字个数都是t-1。
B-TREE-DELETE-NONONE(x,k)
1 i=1
2 ifx.leaf // case1:关键字k在结点x中,并且x叶节点。疑问,如果该叶子结点关键字个数是t-1个呢(后面有回答,尽请关注)
3 while i<=x.n and k>x.keyi
4 i=i+1
5 if k==x.keyi
6 for j=i to x.n-1 //前移后面的关键字
7 x.keyj=x.keyj+1
8 x.n=x.n-1
9 DISK-WRITE(x)