习题内容:
1.掌握B树的存贮结构。
2.实现B树中关键字值的插入及删除操作。
B树的定义:
B树也称B-树,它是一颗多路平衡查找树。我们描述一颗B树时需要指定它的阶数,阶数表示了一个结点最多有多少个孩子结点,一般用字母M表示阶数。当M取2时,就是我们常见的二叉搜索树。
一颗M阶的B树定义如下:
1)每个结点最多有M-1个关键字。
2)根结点最少可以只有1个关键字。
3)非根结点至少有Math.ceil(M / 2)-1个关键字。
4)每个结点中的关键字都按照从小到大的顺序排列,每个关键字的左子树中的所有关键字都小于它,而右子树中的所有关键字都大于它。
5)所有叶子结点都位于同一层,或者说根结点到每个叶子结点的长度都相同。
代码实现:
/*测试环境:VS2017*/
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef struct _BTreeNode
{
int key_count;
int* key;
bool leaf;
_BTreeNode** child;
}BTreeNode, *PBTreeNode;
class BTree
{
private:
PBTreeNode root;
int t;//B树的度,树的阶数为2t***m=2t,t=m/2
public:
BTree(int m):root(NULL), t(m){}//构造
~BTree(){DeleteTree(root);delete root;}//析构
//基本操作:插入,删除,打印,查询
void Insert(int key);
void Delete(int key) { DeleteNonHalf(root, key); }
void Display() { Print(root); }
bool Search(int key);
private:
PBTreeNode SearchBT(PBTreeNode pNode, int key);
PBTreeNode AllocateNode();//划分节点,初始化
PBTreeNode UnionChild(PBTreeNode pParent, PBTreeNode pCLeft, PBTreeNode pCRight, int index);//结合兄弟节点
int Max(PBTreeNode pNode);
int Min(PBTreeNode pNode);
void DeleteNonHalf(PBTreeNode pNode, int key);//删除不足的节点
void InsertNonfull(PBTreeNode pNode, int key);//插入未满的节点
void SplitChild(PBTreeNode pParent, int index, PBTreeNode pChild);//划分子节点
void DeallocateNode(PBTreeNode pNode);//解除划分
void DeleteTree(PBTreeNode pNode);//删除树
void Print(PBTreeNode pNode);//打印树
};
void BTree::Insert(int key)
{
PBTreeNode r = root;
if (r == NULL)
{
r = AllocateNode();
r->leaf = true;
r->key_count = 0;
root = r;
}
if (r != NULL && r->key_count == (2 * t - 1))
{
PBTreeNode s = AllocateNode();
root = s;
s->leaf = false;
s->key_count = 0;
s->child[1] = r;
SplitChild(s, 1, r);
InsertNonfull(s, key);
}
else
{
InsertNonfull(r, key);
}
cout << "成功插入关键字:" << key << endl;
}
bool B