根据算法导论写的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 --;
}