[C++] B树的简单实现

template<class K,size_t M = 1024>
struct BTreeNode{
  K _key[M];
  BTreeNode<K,M>* _sub[M+1];    //多给一个方便分裂
  BTreeNode<K,M>* _parent = nullptr;
  size_t _keysize;
};

template<class K,size_t M = 2014>
class BTree{
  typedef BTreeNode<K,M> Node;

public:
  bool Insert(const K& k){
    //树为空的插入
    if(_root == nullptr){
      _root = new Node;
      _root->_key[0] = k;
      _root->keysize = 1;
      return true;
    }
    //树不为空的插入:往叶子结点中插入
    Node* parent = nullptr;
    Node* cur = _root;
    while(cur){
      size_t i = 0;
      for(;i < cur->keysize;++i){
        if(cur->_key[i] < k){   //在右边
          ++i;
        }
        else if(cur->_key[i] > k){  //在左子树
          break;  //break下次循环会在找到的左子树的0号下标开始查找
        }
        else{   //相等
          return false; //有了就不插入了
        }
      }
      parent = cur;
      cur = cur->_sub[i];
    }
    //cur走到空了,parent指向了要插入结点的父亲
    Node* node = parent;
    K key = k;
    Node* sub = nullptr;

    //node key sub
    while(1){
      //向cur插入k
      InsertKey(node,key,sub);

      if(node->_keysize < M){    //结点没有满
        return true;
      }

      //满了,分裂:找到原中位数,后半段拷贝过去
      Node* splite_Node;
      size_t mid = M / 2;
      //[0,mid-1] mid [mid+1,M-1]

      size_t j = 0;
      for(size_t i = mid - 1;i < M;++i){
        splite_Node->_key[j] = node->_key[i];
        splite_Node->_sub[j] = node->_sub[i];
        ++j;
        splite_Node->_keysize++;
      }
      node->_keysize -= splite_Node->_keysize; 
      node->_keysize--; //mid要提到父亲节点中去

      if(node == _root){  //如果分裂的是根,则产生一个新的根
        _root = new Node;
        _root->key[0] = node->key[mid];

        _root->sub[0] = node;
        _root->sub[1] = splite_Node;
        _root->_keysize = 1;
        return true;
      }
      else{
        key = node->_key[mid];
        node = node->_parent;
        sub = splite_Node;
      }
    }
  }

private:
  Node* _root;
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

giturtle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值