B+树的插入 删除 我了解了吗

Deletion of a node in a B+ Tree:

  • Descend to the leaf where the key exists.
  • Remove the required key and associated reference from the node.
  • If the node still has enough keys and references to satisfy the invariants, stop
  • If the node has too few keys to satisfy the invariants, but its next oldest or next youngest sibling at the same level has more than necessary, distribute the keys between this node and the neighbor. Repair the keys in the level above to represent that these nodes now have a different “split point” between them; this involves simply changing a key in the levels above, without deletion or insertion.
  • If the node has too few keys to satisfy the invariant, and the next oldest or next youngest sibling is at the minimum for the invariant, then merge the node with its sibling; if the node is a non-leaf, we will need to incorporate the “split key” from the parent into our merging.
  • In either case, we will need to repeat the removal algorithm on the parent node to remove the “split key” that previously separated these merged nodes — unless the parent is the root and we are removing the final key from the root, in which case the merged node becomes the new root (and the tree has become one level shorter than before).

Insertion of node in a B+ Tree:

  • Allocate new leaf and move half the buckets elements to the new bucket.
  • Insert the new leaf’s smallest key and address into the parent.
  • If the parent is full, split it too.
  • Add the middle key to the parent node.
  • Repeat until a parent is found that need not split.
  • If the root splits, create a new root which has one key and two pointers. (That is, the value that gets pushed to the new root gets removed from the original node)
	procedure insert(value K,pointer P){
		if(树为空){
			创建一个空叶结点。同时其为根结点
		}else {
			找到对应关键字K的叶子结点L
		}
		if(结点L所含关键字记录少于 n -1 个){
			insert_in_leaf(L,K,P);
		}else{//此时叶节点已经含有n-1个关键字记录 分裂
			创建结点L'
			把 L.P1 ... L.K(n-1) 复制到可以存储n个(指针,搜索码)对的内存块T
			insert_in_leaf(T,K,P);
			令L'.Pn = L.Pn;//修改指针
			令L.Pn = L'//修改指针
			从L中删除L.P1,...,L.K(n-1)
			把T.P1...T.K(n/2) 复制到L中,以L.P1作为开始
			把T.K(n/2)+1,....T.Kn 复制到L'中,以L'.P1作为开始
			令K'表示L'中最小的搜索码值
			insert_in_parent(L,K',L');
		}
	}

	procedure insert_in_leaf(Node L,value K,pointer P){
		if(K < L.K1){
			把 P,K 插入L中,紧接在L.P1的前面
		}else{
			令Ki表示L中小于K的最大搜索码值
			把P K 插入到L中,紧接在L.Ki 的后面
		}
	}

	procedure insert_in_parent(Node N,value K',Node N'){
		if(N 是 根结点){
			创建新结点R,包含N,K',N'//N N'均为指针
			令为树的根结点

		}
		令P = parent(N);
		if(P包含的指针小于n个){
			将(K',N')插入P中N的后面
		}else{//需要分裂P
			将P中指针和索引值对 复制到可以存储P以及以及(N',K')的内存块T中
			把(K',N')插入到T中紧跟在N的后面
			删除P中所有项;创建结点P';
			复制T.P1 ...T.Pceil(n/2)到P;
			令K'' = T.Kceil(n/2)
			复制T.Pceil(n/2)+1 ... T.P(n+1) 到P'

			insert_in_parent(P,K'',P');
		}

	}

procedure delete(value K,poniter P){
	找到包含(K,P)所在的叶结点L
	delete_entry(L,K,P);
}
procedure delete_entry(Node N,value K,pointer P){
	从结点N中删除(K,P);
	if(N 是根结点且只有一个子节点){
		使得N的子节点成为新的根结点,并删除N
	}else if(N 的指针过少){
		令N' 为parent(N)的前一子女或者后一子女
		令K' 为parent(N)中指针N 和N'之间的值
		if(N和N'中的键值记录能够放在一个结点中){//和并结点
			if(N是N'的前驱){
				swap_variables(N,N');
			}
			if(N是非叶结点){
				将N中所有的指针附加到N'中

			}else{
				将N中所有(Ki,Pi)附加到N'中;
				置N'.Pn = N.Pn
			}
			delete_entry(parent(N),K',N)

		}else{//如果不能合并结点
			if(N' 是N的前驱){
				if(N是非叶结点){
					令m满足 N'.Pm是N'最后一个指针;
					从N'中去除(N'.K(m-1),N'.Pm)
					插入(N'.Pm,K')并通过移动N中其他指针和值使其成为N中第一个指针和值
					用N.Km-1 替换parent(N)中的K';
				}else{
					令m满足((N'.Pm,N'.Km)是N'的最后一个指针/值对);
					从N'中去除(N'.Pm,N'.Km);
					插入(N'.Pm,N'.Km)并通过其他指针右移是指成为N中第一个指针/值对
					并用N'.Km 代替 parent(N)的K'
				}
			}else{
				//对称的情况
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值