引言
关于B树的性质
一、B树的结构
二、B树的实现
#include<iostream>
using namespace std;
#if 1
#define M 5
#define MAXSIZE (M-1)
#define MINSIZE (M/2)
class Btree
{
public:
using KeyType = char;
typedef struct {
KeyType key;
void* infoptr;
}ElemType;
typedef struct BNode
{
int keysize;
struct BNode* parent;
ElemType data[M + 1];
struct BNode* sub[M + 1];
}BNode;
class ResultNode {
public:
BNode* pnode;
int index;
bool tag;
public:
ResultNode() :pnode(nullptr), index(-1), tag(false) {}
~ResultNode() {}
};
BNode* BuyBNode()
{
BNode* s = (BNode*)malloc(sizeof(BNode));
if (nullptr == s) exit(-1);
memset(s, 0, sizeof(BNode));
return s;
}
BNode* MakeRoot(const ElemType& item, BNode* left, BNode* right)
{
BNode* root = BuyBNode();
root->keysize = 1;
root->parent = nullptr;
root->data[1] = item;
if (nullptr != left)
{
left->parent = root;
}
if (nullptr != right)
{
right->parent = root;
}
root->sub[0] = left;
root->sub[1] = right;
return root;
}
void Insert_Item(BNode* ptr, int pos, const ElemType& item, BNode* right)
{
for (int i = ptr->keysize; i > pos; --i)
{
ptr->data[i + 1] = ptr->data[i];
ptr->sub[i + 1] = ptr->sub[i];
}
ptr->data[pos + 1] = item;
ptr->sub[pos + 1] = right;
++ptr->keysize;
}
ElemType MoveElem(BNode* s, BNode* ptr, int pos)
{
for (int i = 0, j = pos + 1; j <= ptr->keysize; ++i, ++j)
{
s->data[i] = ptr->data[j];
s->sub[i] = ptr->sub[j];
if (s->sub[i] != nullptr)
{
s->sub[i]->parent = s;
}
}
ptr->keysize = MINSIZE;
s->keysize = MINSIZE;
s->parent = ptr->parent;
return s->data[0];
}
BNode* SplitNewRoot(BNode* ptr)
{
BNode* s = BuyBNode();
ElemType item = MoveElem(s, ptr, MINSIZE);
if (nullptr == ptr->parent)
{
return MakeRoot(item, ptr, s);
}
BNode* pa = ptr->parent;
int pos = pa->keysize;
pa->data[0] = item;
while (pos > 0 && item.key < pa->data[pos].key)
{
--pos;
}
Insert_Item(pa, pos, item, s);
if (pa->keysize > MAXSIZE)
{
return SplitNewRoot(pa);
}
else
{
return nullptr;
}
}
private:
BNode* root;
int size;
public:
Btree() :root(nullptr), size(0) {}
~Btree() {}
BNode* GetRoot()const
{
return root;
}
ResultNode FindKey(KeyType ch)
{
ResultNode res;
BNode* p = root;
while (p != nullptr)
{
p->data[0].key = ch;
int index = p->keysize;
while (index > 0 && ch < p->data[index].key)
{
--index;
}
res.pnode = p;
res.index = index;
if (index > 0 && ch == p->data[index].key)
{
res.tag = true;
break;
}
p = p->sub[index];
}
return res;
}
bool Insert(const ElemType& item)
{
if (nullptr == root)
{
root = MakeRoot(item, nullptr, nullptr);
size = 1;
return true;
}
ResultNode res = FindKey(item.key);
if (res.pnode != nullptr && res.tag) return false;
BNode* ptr = res.pnode;
int pos = res.index;
Insert_Item(ptr, pos, item, nullptr);
if (nullptr != ptr && ptr->keysize > MAXSIZE)
{
BNode* newroot = SplitNewRoot(ptr);
if (newroot != nullptr)
{
root = newroot;
}
}
++size;
return true;
}
void BTreeShow(BNode* ptr)
{
if (nullptr == ptr) return;
BTreeShow(ptr->sub[0]);
for (int i = 1; i <= ptr->keysize; ++i)
{
cout << ptr->data[i].key;
BTreeShow(ptr->sub[i]);
}
}
};
三、插入、查询、输出测试
int main()
{
Btree::KeyType ch[] = {"heqwertsycjgkzlxlowrd"};
Btree bt;
int i = 0;
while(ch[i] != '\0')
{
Btree::ElemType tmp = { ch[i], nullptr };
cout << bt.Insert(tmp);
++i;
}
cout << endl;
bt.BTreeShow(bt.GetRoot());
return 0;
}