b树

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; } } }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值