B-树

根据算法导论写的B-树,B-树删除节点比较麻烦。删除的时候需要考虑较多的方面。



#include<iostream>
#define T 3
using namespace std;


struct BNode
{
    int kn;//key num
    int keys[2*T];
    BNode * ck[2*T+1];
    bool leaf ;
    BNode()
    {
        kn = 0;
        leaf = true;
        for (int i = 0;i < 2*T-1;i ++)
        {
            keys[i] = 0;
            ck[i] = 0;
        }
    }
};
struct BTree
{
    BNode *root;
    int t ;
    BTree()
    {
       t = T;
    }
};
struct BRet
{
    BNode * x;
    int i;
};

void b_tree_create(BTree &t);
void b_tree_insert(BTree &t,int value);
void b_tree_spilt_child(BTree&t,BNode*x,int i);
void b_tree_insert_nofull(BTree&t,BNode*x,int i);
void b_tree_print(BNode*x);
BRet b_tree_search(int value,BNode*x);
void b_tree_delete(int value,BNode *t,BTree& rt);
int b_tree_precessor(BNode *x);
int b_tree_successor(BNode *x);
void b_tree_merge_sons(BNode*x,BNode*y,BNode*p,int itarget);
void b_tree_shift_left(BNode*x,BNode*y,BNode*p,int itarget);
void b_tree_shift_right(BNode*x,BNode*y,BNode*p,int itarget);
void tp(int i )
{
    //cout << "tp:" << i << endl;
}
int main ()
{
    BTree t;
    b_tree_create(t);
    for (int i = 1;i < 24;i ++)
    {
        b_tree_insert(t,i);
    }
    b_tree_print(t.root);

   // b_tree_delete(1,t.root,t);
  //  b_tree_print(t.root);

  //  b_tree_delete(6,t.root,t);
  //  b_tree_print(t.root);


 //   b_tree_delete(1,t.root,t);
    //b_tree_print(t.root);
    for (int i = 1;i < 24;i ++)
    {
        cout <<"********" <<i << "*********"<<  endl;
        b_tree_delete(i,t.root,t);
        b_tree_print(t.root);
    }
    //BRet rt = b_tree_search(2,t.root);
    //cout << rt.i << endl;
   // cout << rt.x->keys[rt.i] <<endl;
}
void b_tree_create(BTree &t)
{
    BNode *x = new BNode();
    t.root = x;
    return ;
}

void b_tree_insert(BTree &t,int value)
{
    BNode * r = t.root;
    if (r->kn == t.t*2 -1)
    {
        tp(2);
        BNode * s = new BNode();
        t.root = s;
        s->kn = 0;
        s->leaf = false;
        s->ck[1] = r;
        tp(3);
        b_tree_spilt_child(t,s,1);
        tp(4);
        b_tree_insert_nofull(t,s,value);

    }
    else
    {
        b_tree_insert_nofull(t,r,value);
    }
}
void b_tree_spilt_child(BTree&t,BNode*x,int i)
{
    BNode * z = new BNode();
    BNode * y = x->ck[i];
    z->leaf = y->leaf;
    z->kn = t.t-1;
    for (int j =1; j<= t.t-1;j ++)
    {
        z->keys[j] = y->keys[j+t.t];
    }

    if (!z->leaf)
    {
        for (int j = 1;j <= t.t;j ++)
        {
            z->ck[j] = y->ck[j+t.t];
        }
    }
    y->kn = t.t-1;
    for (int j = x->kn +1 ;j >= i+1;j --)
    {
        x->ck[j+1] = x->ck[j];
    }
    x->ck[i+1] = z;
    for (int j = x->kn;j >= i;j--)
    {
        x->keys[j+1] = x->keys[i];
    }
    x->keys[i] = y->keys[t.t];
    x->kn = x->kn+1;
}

void b_tree_insert_nofull(BTree&t,BNode*x,int k)
{
    int i = x->kn;
    if(x->leaf)
    {
       // tp(k);
        while (i >=1 && k < x->keys[i])
        {
            x->keys[i+1] = x->keys[i];
            i = i-1;
        }
        x->keys[i+1] = k;
        x->kn = x->kn+1;
    }
    else
    {
        while (i >= 1 && k< x->keys[i])
        {
            i --;
        }
        i = i+1;
        if(x->ck[i]->kn == 2*t.t-1)
        {
            b_tree_spilt_child(t,x,i);
            if(k>x->keys[i])
            {
                i = i+1;
            }
        }
        b_tree_insert_nofull(t,x->ck[i],k);
    }
}

void b_tree_print(BNode*x)
{
    if (NULL == x) return;
    cout <<x->leaf << " " << x->kn << " | ";
    for (int i = 1;i <= x->kn;i ++)
    {
        cout << x->keys[i] << " " ;
    }
    cout << endl;
    if(!x->leaf)
    {
        for(int i = 1;i <= x->kn+1; i++)
        {
            b_tree_print(x->ck[i]);
        }
    }
}

BRet b_tree_search(int value,BNode*x)
{
    BRet rt;
    int i = 1;
    while (i<=x->kn && value > x->keys[i])
    {
        i++;
    }
    if(i<=x->kn && value == x->keys[i])
    {
        rt.i = i;
        rt.x = x;
        return rt;
    }
    else if(x->leaf)
    {
        rt.i = 0;
        rt.x = NULL;
        return rt;
    }
    else
    {
       return  b_tree_search(value,x->ck[i]);
    }
}


void b_tree_delete(int target,BNode* t,BTree& rt)
{
    if (true == t->leaf) // leaf node
    {
        tp(13);
        int i = 1;
        while (i <= t->kn && target > t->keys[i]) i ++;
        if (target == t->keys[i])
        {
            for (; i < t->kn;i ++)
            {
                t->keys[i] = t->keys[i+1];
            }
            t->kn --;
        }
        else
        {
            cout << "value does not exist!" << endl;
        }
    }
    else
    {
        tp(14);
        int i = 1;
        while (i <= t->kn && target > t->keys[i]) i ++;
        //cout << i<< target<<endl;
        if(i <= t->kn && t->keys[i] == target)//t是内部节点
        {
            //cout << t->keys[i];
            //tp(15);
            BNode * y = t->ck[i];
            BNode * z = t->ck[i+1];
            if(y->kn >= rt.t)
            {
                int pre = 0;
                pre = b_tree_precessor(y);
                t->keys[i] = pre;
                b_tree_delete(pre,y,rt);
            }
            else if(z->kn >= rt.t)
            {
                int suc = 0;
                suc = b_tree_successor(z);
                t->keys[i] = suc;
                b_tree_delete(suc,z,rt);
            }
            else
            {
                b_tree_merge_sons(y,z,t,i);
                if(t->kn < 1 && rt.root == t) // root
                {
                    rt.root = y;
                }
                b_tree_delete(target,y,rt);
            }
        }
        else
        {
            tp(16);
            BNode *y = 0;
            BNode * z = 0;
            BNode * x = 0;
            y = t->ck[i];
            if(i <t->kn+1)
            {
                z = t->ck[i+1];
            }
            if(i>1)
            {
                x = t->ck[i-1];
            }
            if(y->kn == rt.t-1)
            {
                tp(12);
          //      tp(13);
                if(x && x->kn >= rt.t)
                {
                    b_tree_shift_right(y,x,t,i);
                }
                else if(z&& z->kn >= rt.t)
                {
                    tp(13);
                    b_tree_shift_left(y,z,t,i);
                }
                else
                {
                    if(x)
                    {
                        tp(19);
                        b_tree_merge_sons(x,y,t,i-1);
                        y = x;
                    }else if(z)
                    {
                        tp(17);
                        tp(t->keys[i]);
                        tp(y->keys[1]);
                        tp(z->keys[1]);
                        b_tree_merge_sons(y,z,t,i);
                    }
                    if(t->kn < 1 && t == rt.root)
                    {
                        rt.root = y;
                    }
                }
                 b_tree_delete(target,y,rt);
            }
            else
            {
                b_tree_delete(target,y,rt);
            }
        }
    }
}
int b_tree_successor(BNode * y)
{
    while (!y->leaf)
    {
        y = y->ck[1];
    }
    return y->keys[1];
}
int b_tree_precessor(BNode *x)
{
    while (!x->leaf)
    {
        x = x->ck[x->kn+1];
    }
    return x->keys[x->kn];
}

void b_tree_merge_sons(BNode*x,BNode*y,BNode*p,int itarget)
{
    x->keys[y->kn+1] = p->keys[itarget];
    x->kn++;
    for (int i = 1;i <=y->kn;i ++)
    {
        x->keys[i+x->kn] = y->keys[i];
    }
    for (int i = 1;i <= y->kn+1;i ++)
    {
        x->ck[i+x->kn] = y->ck[i];
    }
    x->kn += y->kn;
    delete y;
    //?
    for (int i = itarget; i <p->kn;i ++ )
    {
        p->keys[i] = p->keys[i+1];
      //  p->ck[i+1] = p->ck[i+2];
    }
    for(int i = itarget+1;i <= p->kn;i ++)
    {
        p->ck[i] = p->ck[i+1];
    }
    p->kn --;
}
void b_tree_shift_left(BNode*x,BNode*y,BNode*p,int itarget)
{
    x->kn ++;
    x->keys[x->kn] = p->keys[itarget];
    x->ck[x->kn+1] = y->ck[1];
    p->keys[itarget] = y->keys[1];

    for (int i = 1;i < y->kn;i ++)
    {
        y->keys[i] = y->keys[i+1];
    }
    for(int i = 1;i <=y->kn;i ++)
    {
        y->ck[i] = y->ck[i+1];
    }
    y->kn --;
}
void b_tree_shift_right(BNode*x,BNode*y,BNode*p,int itarget)
{
    x->kn ++;
    int i = x->kn;
    while(i>=2)
    {
        x->keys[i] = x->keys[i-1];
        i--;
    }
    i = x->kn+1;
    while(i>=2)
    {
        x->ck[i] = x->ck[i-1];
        i--;
    }
    x->keys[1] = p->keys[itarget-1];
    p->keys[itarget-1] = y->keys[y->kn];
    x->ck[1] = y->ck[y->kn+1];
    y->kn --;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值