1.首先是找到插入位置,在这里我们实现了一个函数通过key值来查找要插入结点所应存在的位置,然后返回他的父结点。
pair<Node*, int> Find(const K& key)
{//查找结点,
Node* cur = _root;
Node* parent = NULL;
while (cur)
{
size_t index = 0;
while (index < cur->_size)
{
if (key > cur->_kv[index].first)
index++;
else if (key == cur->_kv[index].first)
return make_pair(cur, index);
else
break;
}
parent = cur;
cur = cur->_sub[index];
}
//返回其父结点
return make_pair(parent, -1);
}
2.找到位置后就插入结点。
void _Insert(Node* cur, const pair<K, V>& newKV, Node* sub)
{
int index = (cur->_size)-1;
while (index >= 0)
{//寻找插入位置
if (newKV.first >= cur->_kv[index].first)
break;
cur->_kv[index + 1] = cur->_kv[index];
cur->_sub[index + 2] = cur->_sub[index + 1];
index--;
}
//放入结点及对应孩子结点
cur->_kv[index + 1] = newKV;
cur->_sub[index + 2] = sub;
//孩子存在,给其父亲赋值
if (sub)
sub->_parent = cur;
cur->_size++;
}
3.插入节点之后,如果发现kv数组已经存满了,则需要对结点进行分裂操作,分裂操作的主要思想为先找到这个结点的key值为中间值的位置,然后从这个位置把结点分为两部分,左边结点为旧结点,右边部分为新开的结点,然后再把中间的位置连同新结点的储存位置插入到父结点之中,然后再重复这个过程,看父结点是否需要分裂。直到B树满足其规则。
bool
Insert(const
pair<K,V>&
kv) {//插入 if
(_root == NULL)
{ _root = new Node;
_root->_kv[0]
= kv; _root->_size++; return true; } pair<Node*,
int> ret = Find(kv.first);
if
(ret.second != -1)
return false; Node*
cur = ret.first; Node*
temp = cur; pair<K,
V>
newKV = kv; Node*
sub = NULL;
while (1)
{//向cur里插入newKV _Insert(cur, newKV, sub); //cur还没装满,返回 if
(cur->_size < M)
return true; //否则开辟新结点 Node*
tmp = new Node;
//把旧结点分成两半,右边的一半存放在新结点内 size_t mid = M
>> 1;
size_t i = mid + 1;
size_t j = 0;
while (i < cur->_size) {//拷贝右侧结点到新结点 tmp->_kv[j] = cur->_kv[i]; cur->_kv[i] = pair<K,
V>();
tmp->_sub[j] = cur->_sub[i]; if
(cur->_sub[i]) cur->_sub[i]->_parent = tmp; i++; j++; tmp->_size++; cur->_size--;
} tmp->_sub[j] = cur->_sub[i]; cur->_sub[i] = NULL;
if
(cur->_sub[i]) cur->_sub[i]->_parent = tmp; if
(cur->_parent) {//将中间元素插入到父结点 newKV = cur->_kv[mid]; sub = tmp; cur->_size--;
cur = cur->_parent; } else
{//父结点为空,即根结点需要分裂 Node*
newRoot = new Node;
newRoot->_kv[0]
= cur->_kv[mid]; newRoot->_size = 1;
newRoot->_sub[0]
= cur; cur->_parent = newRoot; newRoot->_sub[1]
= tmp; tmp->_parent = newRoot; cur->_size--;
_root = newRoot; return true; } } }