B树代码

本文介绍了如何在B树的实现中添加断言检查以增强Debug模式下的调试能力,并利用STL来管理内存,实现代码的泛型化,提升代码的可复用性和效率。
摘要由CSDN通过智能技术生成

#include "xulity.h"
#include <functional>
#include <tuple>
#include <cassert>

enum class FindEnum
{
    FIND_FAIL = 0,
    FIND_SUCE = 1,
};

template<typename Ty>
struct BTreeNode
{
    typedef BTreeNode<Ty>* node_ptr;
    typedef uint32_t size_type;

    node_ptr parent;         //父指针
    node_ptr *container;     //子节点列表
    Ty *keylist;             //关键字列表
    size_type keynum;          //个数
    bool isleaf;             //是否是叶子节点(true),不是false
};

template<typename Ty, typename Alloc = AllocNode>
class BTree
{
    typedef BTreeNode<Ty> MyBase;
    typedef typename MyBase::node_ptr node_ptr;
    typedef MyBase& node_ref;
    typedef const node_ptr const_node_ptr;
    typedef const node_ref const_node_ref;
    typedef typename MyBase::size_type size_type;
    typedef std::function<int(const Ty&, const Ty&)> compare;
    typedef std::tuple<FindEnum, node_ptr, size_type, size_type> find_result;
public:
    BTree(size_type ChildNum, compare func)
        :MyHead(nullptr), MyChildNum(ChildNum), MyCompare(func)
    {}

    ~BTree()
    {
        if (MyHead)
        {
            clear(MyHead);
        }
    }
    void insert(const Ty& Val)
    {
        insert(MyHead, Val);
    }

    void clear()
    {
        clear(MyHead);
    }

    node_ptr& find(const Ty& data) const
    {
        return find(MyHead, data).get<1>();
    }

    void eraser(const Ty& data)
    {
        eraser(MyHead, data);
    }
private:
    size_type get_max_key() const
    {
        return MyChildNum - 1;
    }

    size_type get_max_child() const
    {
        return MyChildNum;
    }

    size_type get_mid_num() const
    {
        return CEILING_DIV_2(MyChildNum);
    }
    //需把要删除关键字的结点与其左(或右)兄弟结点以及双亲结点中分割二者的关键字合并成一个结点, 
    //即在删除关键字后,该结点中剩余的关键字加指针,加上双亲结点中的关键字Ki一起,
    //合并到Ai(是双亲结点指向该删除关键字结点的左(右)兄弟结点的指针)所指的兄弟结点中去。
    void mergy_node(node_ptr left, node_ptr right, size_type key_index, size_type child_index, bool mergy_format)
    {
        size_type i = 0,j = 0;
        auto parent = left->parent;

        if (mergy_format)
        {
            //将左节点keyIndex后的所有节点往前移//删除key_index指向关键字
            for (i = key_index; i < left->keynum - 1; ++i)
            {
                left->keylist[i] = left->keylist[i + 1];
                left->container[i + 1] = left->container[i + 2];
            }
            //加入父节点元素
            left->keylist[i] = parent->keylist[child_index];
            //加入把右节点的所有元素
            for (j = 0, i = left->keynum; j < right->keynum; j++,i++)
            {
                left->keylist[i] = right->keylist[j];
                left->container[i] = right->container[j];
                if (right->container[j])
                    right->container[j]->parent = left;//重新指定父亲节点
            }
            left->keylist[i] = right->keylist[j];
            if (right->container[j])
            {
                right->container[j]->parent = left;
            }
        } 
        else
        {
            //加入父节点元素
            right->keylist[right->keynum] = parent->keylist[child_index];
            //加入把右节点除被删除元素外的所有元素
            for (j = 0, i = left->keynum; j < key_index; j++, i++)
            {
                left->keylist[i] = right->keylist[j];
                left->container[i] = right->container[j];
                if (right->container[j])
                    right->container[j]->parent = left;//重新指定父亲节点
            }
            left->keylist[i] = right->keylist[j];
            if (right->container[j])
            {
                right->container[j]->parent = left;
            }
            for (j = key_index + 1; i < right->keynum; ++j,++i)
            {
                left->keylist[i] = right->keylist[j];
                left->container[i + 1] = right->container[j + 1];//???
                if (right->container[j + 1])
                    right->container[j + 1]->parent
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值