不太优良的B树。。。调了4天,终于大功告成了。。。
//========================================
//BTreeNode.h
//B树节点类的实现声明
//========================================
#ifndef HEADER_BTREENODE
#define HEADER_BTREENODE
//----------------------------------------
#include
//----------------------------------------
const int m = 5; //BTree的阶数,暂定为5
typedef int KeyType;
class BTreeNode
{
public:
int keyNum;
KeyType key[m];
BTreeNode * child[m+1];
BTreeNode * parent;
void sort()
{
//加入新元素后调整元素及孩子指针的顺序,以满足升序排列要求
if(!isLeaf())
for(int i = keyNum - 1; i > 0 ; i--)
{
if(key[i] >= key[i-1] && child[i+1]->key[0] >= child[i]->key[0])
break;
else
{
if(key[i] < key[i-1])
{
KeyType t;
t = key[i];
key[i] = key[i-1];
key[i-1] = t;
}
if(child[i+1]->key[0] < child[i]->key[0])
{
BTreeNode * pt;
pt = child[i+1];
child[i+1] = child[i];
child[i] = pt;
}
}
}
else
{
for(int i = 1; i < m+1; i++)
child[i] = NULL;
for(int i = keyNum - 1; i > 0 ; i--)
{
if(key[i] >= key[i-1])
break;
else
{
if(key[i] < key[i-1])
{
KeyType t;
t = key[i];
key[i] = key[i-1];
key[i-1] = t;
}
}
}
}
}
BTreeNode()
{
keyNum = 0;
for(int i = 0; i < m+1; i++)
{
child[i] = NULL;
}
parent = NULL;
}
BTreeNode( KeyType & e,BTreeNode * first = NULL,BTreeNode * second = NULL,BTreeNode * p = NULL)
{
for(int i = 0; i < m+1; i++)
child[i] = NULL;
keyNum = 1;
key[0] = e;
child[0] = first;
child[1] = second;
parent = p;
}
~BTreeNode() {}
bool insertVal(KeyType & k,BTreeNode * nd = NULL)
{
//该结点数据存储已满,无法再插入数据
key[keyNum] = k;
child[keyNum+1] = nd;
keyNum++;
sort();
if(keyNum >= m)
return false;
else
return true;
}
bool remove(int n)
{
for(int i = n; i < keyNum - 1; i++)
{
key[i] = key[i+1];
child[i+1] = child[i+2];
}
keyNum--;
return true;
}
bool removeLeafKey(KeyType & k)
{
//对叶子节点中的key进行删除
if(!isLeaf())
return false;
int i = 0;
while(i < keyNum && k != key[i])
i++;
if(i == keyNum)
return false;
else
{
for(int j = i; j < keyNum - 1; j++)
{
key[j] = key[j+1];
child[i+1] = child[i+2];
}
keyNum--;
return true;
}
}
bool isLeaf()
{
if(child[0] == NULL)
return true;
else
return false;
}
};
#endif //HEADER_BTREENODE
//========================================
//BTree.h
//B树类的声明
//========================================
#ifndef HEADER_BTREE
#define HEADER_BTREE
//---------------------------------------
#include "BTreeNode.h"
//---------------------------------------
class BTree
{
public:
BTreeNode * root;
int level; //记录B树的层数
BTree() {root = NULL; level = 0;}
~BTree() {clear();}
BTreeNode * findhelp(BTreeNode * subroot,KeyType & k,int & pos) ;
void clearhelp(BTreeNode * subroot);
void printhelp(BTreeNode * subroot,int level) ;
//重新调整以subroot为根节点的子树的所有节点的parent值
void resetParent(BTreeNode * subroot);
BTreeNode * isBroCan(BTreeNode * node);
void clear()
{
clearhelp(root);
root = NULL;
level = 0;
}
bool insert(KeyType & k);
bool remove( KeyType & k);
BTreeNode * find( KeyType & k,int & pos)
{
return findhelp(root,k,pos);
}
};
#endif //HEADER_BTREE
//========================================
//BTree.cpp
//B树类的实现
//========================================
#include "BTree.h"
//-----------------------------------------
void BTree::clearhelp(BTreeNode * subroot)
{
if( subroot == NULL )
return;
if( subroot -> isLeaf() )
{
delete subroot;
return;
}
for(int i = subroot->keyNum; i >= 0; i--)
{
clearhelp(subroot -> child[i]);
subroot->child[i] = NULL;
}
delete subroot;
}
//-----------------------------------------
void BTree::resetParent(BTreeNode * subroot)
{
if(subroot == NULL || subroot->isLeaf())
return;
for(int i = 0; i <= subroot->keyNum; i++)
{
subroot->child[i]->parent = subroot;
resetParent(subroot->child[i]);
}
}
//-----------------------------------------
BTreeNode * BTree::isBroCan(BTreeNode * node)
{
if(node == root || node == NULL)
return NULL;
BTreeNode * p = node->parent;
//t用于定位该节点是父节点的第t个孩子
int t = 0;
while(t < node->parent->keyNum)
{
if(node->parent->key[t] < node->key[0])
t++;
else
break;
}
if(t == 0)
{
if(node->parent->child[t+1]->keyNum > m/2)
return node->parent->child[t+1];
else
return NULL;
}
else if(t == node->parent->keyNum)
{
if(node->parent->child[t-1]->keyNum > m/2)
return node->parent->child[t-1];
else
return NULL;
}
else
{
if(node->parent->child[t+1]->keyNum > m/2)
return node->parent->child[t+1];
else if(node->parent->child[t-1]->keyNum > m/2)
return node->parent->child[t-1];
else
return NULL;
}
return NULL;
}
//-----------------------------------------
BTreeNode * BTree::findhelp(BTreeNode * subroot, KeyType & k,int & pos)
{
if(subroot == NULL)
return NULL;
for(int i = 0; i < subroot->keyNum; i++)
{
if( k < subroot->key[i] )
return findhelp( subroot->child[i], k ,pos);
else if( k == subroot->key[i] )
{
pos = i;
return subroot;
}
}
return findhelp( subroot->child[subroot->keyNum] ,k,pos);
}
//-----------------------------------------
bool BTree::insert(KeyType & k)
{
//当该树为空
if(root == NULL)
{
root = new BTreeNode (k);
level++;
return true;
}
//不为空则找到一个叶结点node并将k插入
BTreeNode * node = root;
while(!node->isLeaf())
{
if(k > node->key[node->keyNum - 1])
node = node->child[node->keyNum];
else
for(int i = 0; i < node->keyNum; i++)
if( k < node->key[i] )
{
node = node->child[i];
break;
}
else if( k == node->key[i] )
return false;
}
while(true)
{
static BTreeNode * node1 = NULL;
static BTreeNode * node2 = NULL;
if(node->insertVal(k,node2))
{
//若节点node未上溢
resetParent(root); //重新调整node以下的各节点的parents值
return true;
}
else
{
//若发生上溢
node1 = node;
node2 = new BTreeNode; //(node->key[3],node->key[4],node->child[],NULL,node->parent);
int j,i;
for(j = 0 , i = m/2+1; i < m; i++,j++)
{
node2->key[j] = node->key[i];
node2->child[j] = node->child[i];
}
node2->child[j] = node->child[i];
node2->parent = node1->parent;
k = node->key[m/2];
node1->keyNum = m/2;
node2->keyNum = m/2;
if(node == root)
{
root = new BTreeNode (k,node1,node2,NULL);
root->child[0]->parent = root;
root->child[1]->parent = root;
level++;
resetParent(root);
return true;
}
else
node = node->parent;
}
}
return true;
}
//-----------------------------------------
bool BTree::remove( KeyType & k)
{
int pos;
BTreeNode * node = findhelp(root,k,pos);
if(node == NULL)
return false;
else
{
if(!node->isLeaf())
{
//找到k的直接前驱s所在的叶子结点,用s覆盖node中的k
//node赋值为含s叶子结点
//从node中删除s
BTreeNode * t = node->child[pos];
while(!t->isLeaf())
t = t->child[ t->keyNum ];
node->key[pos] = t->key[ t->keyNum - 1 ];
t->remove(t->keyNum - 1);
node = t;
}
else
node->removeLeafKey(k);
while(true)
{
if(node->keyNum >= m/2)
return true;
//如果node的一个兄弟结点中有足够的key
else if(BTreeNode * bro = isBroCan(node))
{
int t = 0;
while(t <= node->parent->keyNum)
{
if(node->parent->key[t] < node->key[0])
t++;
else
break;
}
//在node及bro中重新分配key
if(node->key[0] > bro->key[0])
{
node->insertVal(node->parent->key[t-1]);
node->parent->key[t-1] = bro->key[bro->keyNum - 1];
bro->remove(bro->keyNum - 1);
}
else
{
node->insertVal(node->parent->key[t]);
node->parent->key[t] = bro->key[0];
bro->remove(0);
}
return true;
}
//如果node的父结点为根
else if(node->parent == root)
{
//如果父节点只有一个key
if(node->parent->keyNum == 1)
{
//将root、node及兄弟结点合并成新的根
root->child[0]->insertVal(root->key[0],root->child[1]);
for(int i = 0; i < root->child[1]->keyNum; i++)
{
root->child[0]->child[ root->child[0]->keyNum ] = root->child[1]->child[i];
root->child[0]->insertVal(root->child[1]->key[i],root->child[1]->child[i+1]);
}
BTreeNode * t = root;
root = root->child[0];
root->parent = NULL;
resetParent(root);
level--;
delete t->child[1];
delete t;
return true;
}
else
{
//合并node及兄弟结点
if(node->key[0] < root->key[0])
{
node->insertVal(root->key[0]);
for(int i = 0; i < root->child[1]->keyNum; i++)
{
node->child[ node->keyNum ] = root->child[1]->child[i];
node->insertVal(root->child[1]->key[i]);
}
node->child[ node->keyNum ] = root->child[1]->child[ root->child[1]->keyNum ];
root->remove(0);
}
else
{
int t = 0;
while(t <= node->parent->keyNum)
{
if(node->parent->key[t] < node->key[0])
t++;
else
break;
}
root->child[t]->insertVal(root->key[t]);
for(int i = 0; i < node->keyNum; i++)
{
root->child[t]->child[ root->child[t]->keyNum ] = node->child[i];
root->child[t]->insertVal(node->key[i]);
}
root->child[t]->child[ root->child[t]->keyNum ] = node->child[ node->keyNum ];
delete node;
root->remove(t);
}
return true;
}
} //else if(node->parent == root)
else
{
//合并node及兄弟结点
if(node->key[0] < node->parent->key[0])
{
node->insertVal(node->parent->key[0]);
for(int i = 0; i < node->parent->child[1]->keyNum; i++)
{
node->child[ node->keyNum ] = node->parent->child[1]->child[i];
node->insertVal(node->parent->child[1]->key[i]);
}
node->child[ node->keyNum ] = node->parent->child[1]->child[ node->parent->child[1]->keyNum ];
node->parent->remove(0);
}
else
{
int t = 0;
while(t <= node->parent->keyNum)
{
if(node->parent->key[t] < node->key[0])
t++;
else
break;
}
node->parent->child[t]->insertVal(node->parent->key[t]);
for(int i = 0; i < node->keyNum; i++)
{
node->parent->child[t]->child[ node->parent->child[t]->keyNum ] = node->child[i];
node->parent->child[t]->insertVal(node->key[i]);
}
node->parent->child[t]->child[ node->parent->child[t]->keyNum ] = node->child[ node->keyNum ];
delete node;
node->parent->remove(t);
}
node = node->parent;
}
} //while(true)
}
}