B-Tree

#include <iostream>
using namespace std;

template <class Record, int order>
struct B_node
{
    int cnt;
    Record data[order-1];
    B_node<Record, order> *branch[order];
    B_node() {cnt = 0;}
};

enum Error_code {not_present, duplicate_error, overflow, success};

template<class Record,int order>
class B_tree
{
public:
    B_tree() {root = nullptr;}
    Error_code search_tree(Record &target)
    {
        return recursive_search_tree(root, target);
    }
    Error_code insert(const Record &new_entry);
    Error_code remove(const Record &target);
private:
    B_node<Record, order> *root;
    Error_code recursive_search_tree(B_node<Record, order> *current, Record &target);
    Error_code search_node(B_node<Record, order> *current, const Record &target, int &pos);

    Error_code push_down(B_node<Record, order> *current, const Record &new_entry, Record &median, B_node<Record, order> * &right_branch);
    void push_in(B_node<Record, order> *current, const Record &entry, B_node<Record, order> *right_branch, int pos);
    void split_node(B_node<Record, order> *current, const Record &extra_entry, B_node<Record, order> *extra_branch, int pos, B_node<Record, order> * &right_half, Record &median);

    Error_code recursive_remove(B_node<Record, order> *current, const Record &target);
    void remove_data(B_node<Record, order> *current, int pos)
    {
        for (int i = pos; i < current->cnt-1; ++i)
            current->data[i] = current->data[i+1];
        --current->cnt;
    }
    void copy_in_predecessor(B_node<Record, order> *current, int pos)
    {
        B_node<Record, order> *leaf = current->branch[pos];
        while (leaf->branch[leaf->cnt]) leaf = leaf->branch[leaf->cnt];
        current->data[pos] = leaf->data[leaf->cnt-1];
    }
    void restore(B_node<Record, order> *current, int pos);
    void move_left(B_node<Record, order> *current, int pos);
    void move_right(B_node<Record, order> *current, int pos);
    void combine(B_node<Record, order> *current, int pos);
};

template<class Record, int order>
Error_code B_tree<Record, order>::recursive_search_tree(B_node<Record, order> *current, Record &target)
{
    Error_code result = not_present;
    int pos;
    if (current)
    {
        result = search_node(current, target, pos);
        if (result == not_present)
            result = recursive_search_tree(current->branch[pos], target);
        else
            target = current->data[pos];
    }
    return result;
}

template<class Record, int order>
Error_code B_tree<Record, order>::search_node(B_node<Record, order> *current, const Record &target, int &pos)
{
    pos = 0;
    while (pos < current->cnt && target > current->data[pos]) ++pos;
    if (pos < current->cnt && target == current->data[pos]) return success;
    else return not_present;
}

template<class Record, int order>
Error_code B_tree<Record, order>::insert(const Record &new_entry)
{
    Record median;
    B_node<Record, order> *right_branch, *new_root;
    Error_code result = push_down(root, new_entry, median, right_branch);
    if (result == overflow)
    {
        new_root = new B_node<Record, order>;
        new_root->cnt = 1;
        new_root->data[0] = median;
        new_root->branch[0] = root;
        new_root->branch[1] = right_branch;
        root = new_root;
        result = success;
    }
    return result;
}

template<class Record, int order>
Error_code B_tree<Record, order>::push_down(B_node<Record, order> *current, const Record &new_entry, Record &median, B_node<Record, order> * &right_branch)
{
    Error_code result;
    int pos;
    if (!current)
    {
        median = new_entry;
        right_branch = nullptr;
        result = overflow;
    }
    else
    {
        if (search_node(current, new_entry, pos) == success)
            result = duplicate_error;
        else
        {
            Record extra_entry;
            B_node<Record, order> *extra_branch;
            result = push_down(current->branch[pos], new_entry, extra_entry, extra_branch);
            if (result == overflow)
            {
                if (current->cnt < order-1)
                {
                    result = success;
                    push_in(current, extra_entry, extra_branch, pos);
                }else
                    split_node(current, extra_entry, extra_branch, pos, right_branch, median);
            }
        }
    }
    return result;
}

template<class Record, int order>
void B_tree<Record, order>::push_in(B_node<Record, order> *current, const Record &entry, B_node<Record, order> *right_branch, int pos)
{
    for (int i = current->cnt; i > pos; --i)
    {
        current->data[i] = current->data[i-1];
        current->branch[i+1] = current->branch[i];
    }
    current->data[pos] = entry;
    current->branch[pos+1] = right_branch;
    ++current->cnt;
}

template<class Record, int order>
void  B_tree<Record, order>::split_node(B_node<Record, order> *current, const Record &extra_entry, B_node<Record, order> *extra_branch, int pos, B_node<Record, order> * &right_half, Record &median)
{
    right_half = new B_node<Record, order>;
    int mid = order>>1;
    if (pos <= mid)
    {
        for (int i = mid; i < order-1; ++i)
        {
            right_half->data[i-mid] = current->data[i];
            right_half->branch[i+1-mid] = current->branch[i+1];
        }
        current->cnt = mid;
        right_half->cnt = order - mid - 1;
        push_in(current, extra_entry, extra_branch, pos);
    }
    else
    {
        ++mid;
        for (int i = mid; i < order-1; ++i)
        {
            right_half->data[i-mid] = current->data[i];
            right_half->branch[i+1-mid] = current->branch[i+1];
        }
        current->cnt = mid;
        right_half->cnt = order - 1 - mid;
        push_in(right_half, extra_entry, extra_branch, pos-mid);
    }
    median = current->data[current->cnt-1];
    right_half->branch[0] = current->branch[current->cnt];
    --current->cnt;
}

template <class Record, int order>
Error_code B_tree<Record, order>::remove(const Record &target)
{
    Error_code result;
    result = recursive_remove(root, target);
    if (root && !root->cnt)
    {
        B_node<Record, order> *old_root = root;
        root = root->branch[0];
        delete old_root;
    }
    return result;
}

template <class Record, int order>
Error_code B_tree<Record, order>::recursive_remove(B_node<Record, order> *current, const Record &target)
{
    Error_code result;
    int pos;
    if (!current) result = not_present;
    else
    {
        if (search_node(current, target, pos) == success)
        {
            result = success;
            if (current->branch[pos])
            {
                copy_in_predecessor(current, pos);
                recursive_remove(current->branch[pos], current->data[pos]);
            }
            else remove_data(current, pos);
        }else
            result = recursive_remove(current->branch[pos], target);

        if (current->branch[pos])
            if (current->branch[pos]->cnt < ((order-1)>>1))
                restore(current, pos);
    }
    return result;
}

template <class Record, int order>
void B_tree<Record, order>::restore(B_node<Record, order> *current, int pos)
{
    if (pos == current->cnt)
        if (current->branch[pos-1]->cnt > ((order-1)>>1))
            move_right(current, pos-1);
        else
            combine(current, pos);
    else if (!pos)
        if (current->branch[1]->cnt > ((order-1)>>1))
            move_left(current, 1);
        else
            combine(current, 1);
    else
        if (current->branch[pos-1]->cnt > ((order-1)>>1))
            move_right(current, pos-1);
        else if (current->branch[pos+1]->cnt > ((order-1)>>1))
            move_left(current, pos+1);
        else combine(current, pos);
}

template <class Record, int order>
void B_tree<Record, order>::move_left(B_node<Record, order> *current, int pos)
{
    B_node<Record, order>
        *left_branch = current->branch[pos-1],
        *right_branch = current->branch[pos];
    left_branch->data[left_branch->cnt] = current->data[pos-1];
    left_branch->branch[++left_branch->cnt] = right_branch->branch[0];
    current->data[pos-1] = right_branch->data[0];
    --right_branch->cnt;
    for (int i = 0; i < right_branch->cnt; ++i)
    {
        right_branch->data[i] = right_branch->data[i+1];
        right_branch->branch[i] = right_branch->branch[i+1];
    }
    right_branch->branch[right_branch->cnt] =
    right_branch->branch[right_branch->cnt+1];
}

template <class Record, int order>
void B_tree<Record, order>::move_right(B_node<Record, order> *current, int pos)
{
    B_node<Record, order>
        *right_branch = current->branch[pos+1],
        *left_branch = current->branch[pos];
    right_branch->branch[right_branch->cnt+1] =
    right_branch->branch[right_branch->cnt];
    for (int i = right_branch->cnt; i > 0; --i)
    {
        right_branch->data[i] = right_branch->data[i-1];
        right_branch->branch[i] = right_branch->branch[i-1];
    }
    ++right_branch->cnt;
    right_branch->data[0] = current->data[pos];
    right_branch->branch[0] = left_branch->branch[left_branch->cnt--];
    current->data[pos] = left_branch->data[left_branch->cnt];
}

template <class Record, int order>
void B_tree<Record, order>::combine(B_node<Record, order> *current, int pos)
{
    int i;
    B_node<Record, order>
        *left_branch = current->branch[pos-1],
        *right_branch = current->branch[pos];
    left_branch->data[left_branch->cnt] = current->data[pos-1];
    left_branch->branch[++left_branch->cnt] = right_branch->branch[0];
    for (i = 0; i < right_branch->cnt; ++i)
    {
        left_branch->data[left_branch->cnt] = right_branch->data[i];
        left_branch->branch[++left_branch->cnt] = right_branch->branch[i+1];
    }
    --current->cnt;
    for (i = pos-1; i < current->cnt; ++i)
    {
        current->data[i] = current->data[i+1];
        current->branch[i+1] = current->branch[i+2];
    }
    delete right_branch;
}

int main()
{
    B_tree<char, 5> mybtree;
    mybtree.insert('a');
    mybtree.insert('g');
    mybtree.insert('f');
    mybtree.insert('b');
    mybtree.insert('k');
    mybtree.insert('d');
    mybtree.insert('h');
    mybtree.insert('m');
    mybtree.insert('j');
    mybtree.insert('e');
    mybtree.insert('s');
    mybtree.insert('i');
    mybtree.insert('r');
    mybtree.insert('x');
    mybtree.insert('c');
    mybtree.insert('l');
    mybtree.insert('n');
    mybtree.insert('t');
    mybtree.insert('u');
    mybtree.insert('p');
    char target = 'k';
    cout << mybtree.search_tree(target);
    mybtree.remove('k');
    cout << mybtree.search_tree(target);
    cin.get();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值