B+树的实现,主要讲解删除操作

关于B+树的基本定义,随便一本数据结构的书或者算法导论中都有,就不做介绍了。虽然网上和书本上都有很多对B+树的介绍,但是有很多资料对于B+树的操作或者介绍不全,或者有描写错误的地方,我这里参考这位大神的文章http://blog.csdn.net/xinghongduo/article/details/7059459,整理了B+树删除操作的所有情况,并且抽出了两个辅助函数://向相邻节点借用关
摘要由CSDN通过智能技术生成

关于B+树的基本定义,随便一本数据结构的书或者算法导论中都有,就不做介绍了。虽然网上和书本上都有很多对B+树的介绍,但是有很多资料对于B+树的操作或者介绍不全,或者有描写错误的地方,我这里参考这位大神的文章http://blog.csdn.net/xinghongduo/article/details/7059459,整理了B+树删除操作的所有情况。

我用visio画了删除操作可能出现的情况总结,如下图(在网页上看的话字体太小了,推荐下载到本地或者放大再看):



对应上图的删除部分代码如下所示:

void    BPlusTree::delete_BPlus_tree(FILEP current, TRecord &record)
{
	int i, j;

	BPlusNode x;
	ReadBPlusNode(current, x);


	for (i = 0; i < x.nkey && record.key > x.key[i]; i++);

	if (i < x.nkey && x.key[i] == record.key)  //在当前节点找到关键字  
	{

		if (!x.isleaf)     //在内节点找到关键字  
		{
			BPlusNode child;
			ReadBPlusNode(x.Pointer[i], child);

			if (child.isleaf)     //如果孩子是叶节点  
			{
				if (child.nkey > MAX_KEY / 2)      //情况A  
				{     //1、找到关键字,当前节点是内节点,孩子是叶子节点,孩子节点半满
					  //直接删除
					x.key[i] = child.key[child.nkey - 2];
					child.nkey--;

					WriteBPlusNode(current, x);
					WriteBPlusNode(x.Pointer[i], child);
                    //删除完就return了
					return;
				}
				else    //否则孩子节点的关键字数量不过半  
				{
					if (i > 0)      //有左兄弟节点  
					{
						BPlusNode lbchild;
						ReadBPlusNode(x.Pointer[i - 1], lbchild);
						//2、找到关键字,当前节点是内节点,孩子是叶子节点,孩子节点不半满,左孩子半满
						//向左孩子借record									
						if (lbchild.nkey > MAX_KEY / 2)        //情况B  
						{
							//右移键值和指针
							for (j = child.nkey; j > 0; j--)
							{
								child.key[j] = child.key[j - 1];
								child.Pointer[j] = child.Pointer[j - 1];
							}
                            //下放父节点键值和指针
							child.key[0] = x.key[i - 1];
							child.Pointer[0] = lbchild.Pointer[lbchild.nkey - 1];

							child.nkey++;

							lbchild.nkey--;
                            //更新父节点键值和指针
							x.key[i - 1] = lbchild.key[lbchild.nkey - 1];
							x.key[i] = child.key[child.nkey - 2];
                            //写回
							WriteBPlusNode(current, x);
							WriteBPlusNode(x.Pointer[i - 1], lbchild);
							WriteBPlusNode(x.Pointer[i], child);

						}
						else    //情况C  
						{
							//3、找到关键字,当前节点是内节点,孩子是叶子节点,孩子节点不半满,左孩子也不半满
							//向左孩子合并,child页加入freelist
							//拷贝
							for (j = 0; j < child.nkey; j++)
							{
								lbchild.key[lbchild.nkey + j] = child.key[j];
								lbchild.Pointer[lbchild.nkey + j] = child.Pointer[j];
							}
							lbchild.nkey += child.nkey;

							lbchild.Pointer[MAX_KEY] = child.Pointer[MAX_KEY];


							//更新当前内节点
							for (j = i - 1; j < x.nkey - 1; j++)
							{
								x.key[j] = x.key[j + 1];
								x.Pointer[j + 1] = x.Pointer[j + 2];
							}
							x.nkey--;
							//i-1指向新的lbchild右端(末端)
							
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值