数据结构实验—b/b+树(人机交互友好,C/C++)
代码很长,关键部分都给了注释,耐心阅读,建议理解b/b+树后阅读
b树
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include<algorithm>
#include<iostream>
#include<time.h>
#define DEGREE 3
typedef int key_value;
typedef struct _btree_node {
key_value* keys;
struct _btree_node** childrens;
int num;
int leaf;
} btree_node;
typedef struct _btree {
btree_node* root;
int t;
} btree;
btree_node* btree_create_node(int t, int leaf) {
btree_node* node = (btree_node*)calloc(1, sizeof(btree_node));
if (node == NULL) assert(0);
node->leaf = leaf;
node->keys = (key_value*)calloc(1, (2 * t - 1) * sizeof(key_value));
node->childrens = (btree_node**)calloc(1, (2 * t) * sizeof(btree_node));
node->num = 0;
return node;
}
void btree_destroy_node(btree_node* node) {
assert(node);
free(node->childrens);
free(node->keys);
free(node);
}
void btree_create(btree* T, int t) {
T->t = t;
btree_node* x = btree_create_node(t, 1);
T->root = x;
}
void btree_split_child(btree* T, btree_node* x, int i) {
int t = T->t;
//分裂后一个结点变成两个结点,所以需要再创建一个新结点z
//用来存储分裂后的另一个结点的信息,其叶子属性与原结点y相同
btree_node* y = x->childrens[i];
btree_node* z = btree_create_node(t, y->leaf);
//分裂后新结点key值数为[m/2] - 1
z->num = t - 1;
int j = 0;
for (j = 0; j < t - 1; j++) {
//原y的右半部分key赋值给z
z->keys[j] = y->keys[j + t];
}
if (y->leaf == 0) {
//如果不是叶子节点,有子树,子树的地址也要复制一份
for (j = 0; j < t; j++) {
z->childrens[j] = y->childrens[j + t];
}
}
//分出去后,y的key值个数也变成t-1
y->num = t - 1;
for (j = x->num; j >= i + 1; j--) {
x->childrens[j + 1] = x->childrens[j];
}
//父节点的A[i+1]位置的指针赋值给新的z(注意这里父节点必然是非满的)
x->childrens[i + 1] = z;
//i+1的位置给了z,原父节点的key值对应挪动
for (j = x->num - 1; j >= i; j--) {
x->keys[j + 1] = x->keys[j];
}
x->keys[i] = y->keys[t - 1];
x->num += 1;
}
void btree_insert_nonfull(btree* T, btree_node* x, key_value k) {
int i = x->num - 1;
if (x->leaf == 1) {
//如果当前是往叶子
while (i >= 0 && x->keys[i] > k) {
x->keys[i + 1] = x->keys[i];
i--;
}
x->keys[i + 1] = k;
x->num += 1;
}
else {
while (i >= 0 && x->keys[i] > k) i--;
if (x->childrens[i + 1]->num == (2 * (T->t)) - 1) {
btree_split_child(T, x, i + 1);
if (k > x->keys[i + 1]) i++;
}
btree_insert_nonfull(T, x->childrens[i + 1], k);
}
}
void btree_insert(btree* T, key_value key) {
//int t = T->t;
btree_node* r = T->root;
if (r->num == 2 * T->t - 1) {
btree_node* node = btree_create_node(T->t, 0);
T->root = node;
node->childrens[0] = r;
btree_split_child(T, node, 0);
int i = 0;
if (node->keys[0] < key) i++;
btree_insert_nonfull(T, node->childrens[i], key);
}
else {
btree_insert_nonfull(T, r, key);
}
}
void btree_traverse(btree_node* x) {
int i = 0;
for (i = 0; i < x->num; i++) {
if (x->leaf == 0)
btree_traverse(x->childrens[i]);
printf("%d ", x->keys[i]);
}
if (x->leaf == 0) btree_traverse(x->childrens[i]);
}
void btree_print(btree* T, btree_node* node, int layer)
{
btree_node* p = node;
int i;
if (p) {
printf("\nlayer = %d keynum = %d is_leaf = %d\n", layer, p->num, p->leaf);
for (i = 0; i < node->num; i++)
printf("%d ", p->keys[i]);
printf("\n");
#if 0
printf("%p\n", p);
for (i = 0; i <= 2 * T->t; i++)
printf("%p ", p->childrens[i]);
printf("\n");
#endif
layer++;
for (i = 0; i <= p->num; i++)
if (p->childrens[i])
btree_print(T, p->childrens[i], layer);
}
else printf("the tree is empty\n");
}
//low一般为1,high为n
//这里仅是一个结点的查找方法,外层再加一个从根到叶子节点的查找while(node->leaf != 1)即可
int btree_bin_search(btree_node* node, int low, int high,key_value key) {
int mid;
if (low > high || low < 0 || high < 0) {
return -1;
}
while (low <= high) {
mid = (low + high) / 2;
if (key > node->keys[mid]) {
low = mid + 1;
}
else {
high = mid - 1;
}
}
//假如key值大于最于Kn,那么返回n值,以便从An所指的结点继续查找,假如小于A0,返回的为0,从A0所指的结点继续查找,直到叶子节。
return low;
}
int btree_search(btree_node* node, int key)
{
int pos = btree_bin_search(node, 0, node->num-1, key);
if (node->keys[pos] == key)
return pos;
while (node->leaf != 1)
{
node = node->childrens[pos];
pos = btree_bin_search(node, 0, node->num-1, key);
if (node->keys[pos] == key)
return pos;
}
return -1;
}
//{child[idx], key[idx], child[idx+1]}
void btree_merge(btree* T, btree_node* node, int idx) {
btree_node* left = node->childrens[idx];
btree_node* right = node->childrens[idx + 1];
int i = 0;
//data merge
left->keys[T->t - 1] = node->keys[idx];
for (i = 0; i < T->t - 1; i++) {
left->keys[T->t + i] = right->keys[i];
}
if (!left->leaf) {
for (i = 0; i < T->t; i++) {
left->childrens[T->t + i] = right->childrens[i];
}
}
left->num += T->t;
//destroy right
btree_destroy_node(right);
//node
for (i = idx + 1; i < node->num; i++) {
node->keys[i - 1] = node->keys[i];
node->childrens[i] = node->childrens[i + 1];
}
node->childrens[i + 1] = NULL;
node->num -= 1;
if (node->num == 0) {
T->root = left;
btree_destroy_node(node);
}
}
void btree_delete_key(btree* T, btree_node* node, key_value key) {
if (node == NULL) return;
int idx = 0, i;
while (idx < node->num && key > node->keys[idx]) {
idx++;
}
if (idx < node->num && key == node->keys[idx]) {
if (node->leaf) {
for (i = idx; i < node->num - 1; i++) {
node->keys[i] = node->keys[i + 1];
}
node->keys[node->num - 1] = 0;
node->num--;
if (node->num == 0) { //root
free(node);
T->root = NULL;
}
return;
}
else if (node->childrens[idx]->num >= T->t) {
btree_node* left = node->childrens[idx];
node->keys[idx] = left->keys[left->num - 1];
btree_delete_key(T, left, left->keys[left->num - 1]);
}
else if (node->childrens[idx + 1]->num >= T->t) {
btree_node* right = node->childrens[idx + 1];
node->keys[idx] = right->keys[0];
btree_delete_key(T, right, right->keys[0]);
}
else {
btree_merge(T, node, idx);
btree_delete_key(T, node->childrens[idx], key);
}
}
else {
btree_node* child = node->childrens[idx];
if (child == NULL) {
printf("Cannot del key = %d\n", key);
return;
}
if (child->num == T->t - 1) {
btree_node* left = NULL;
btree_node* right = NULL;
if (idx - 1 >= 0)
left = node->childrens[idx - 1];
if (idx + 1 <= node->num)
right = node->childrens[idx + 1];
if ((left && left->num >= T->t) ||
(right && right->num >= T->t)) {
int richR = 0;
if (right) richR = 1;
if (left && right) richR = (right->num > left->num) ? 1 : 0;
if (right && right->num >= T->t && richR) { //borrow from next
child->keys[child->num] = node->keys[idx];
child->childrens[child->num + 1] = right->childrens[0];
child->num++;
node->keys[idx] = right->keys[0];
for (i = 0; i < right->num - 1; i++) {
right->keys[i] = right->keys[i + 1];
right->childrens[i] = right->childrens[i + 1];
}
right->keys[right->num - 1] = 0;
right->childrens[right->num - 1] = right->childrens[right->num];
right->childrens[right->num] = NULL;
right->num--;
}
else { //borrow from prev
for (i = child->num; i > 0; i--) {
child->keys[i] = child->keys[i - 1];
child->childrens[i + 1] = child->childrens[i];
}
child->childrens[1] = child->childrens[0];
child->childrens[0] = left->childrens[left->num];
child->keys[0] = node->keys[idx - 1];
child->num++;
node->keys[idx - 1] = left->keys[left->num - 1];
left->keys[left->num - 1] = 0;
left->childrens[left->num] = NULL;
left->num--;
}
}
else if ((!left || (left->num == T->t - 1))
&& (!right || (right->num == T->t - 1))) {
if (left && left->num == T->t - 1) {
btree_merge(T, node, idx - 1);
child = left;
}
else if (right && right->num == T->t - 1) {
btree_merge(T, node, idx);
}
}
}
btree_delete_key(T, child, key);
}
}
int btree_delete(btree* T, key_value key) {
if (!T->root) return -1;
btree_delete_key(T, T->root, key);
return 0;
}
int main() {
btree T = { 0 };
btree_create(&T, 3);
srand(time(NULL));
int i = 0;
int x;
char key[30] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
/*for (i = 0; i < 26; i++) {
key[i] = rand() % 1000;
printf("%c ", key[i]);
btree_insert(&T, key[i]);
}*/
int n;
printf("请输入要插入的数据个数:\n");
scanf("%d", &n);
printf("请输入要插入的值(n个数字):\n");
for (int i = 0; i < n; i++)
{
x = rand();
btree_insert(&T, x);
}
btree_print(&T, T.root, 0);
/*for (i = 0; i < 26; i++) {
printf("\n---------------------------------\n");
btree_delete(&T, key[25 - i]);
btree_traverse(T.root);
btree_print(&T, T.root, 0);
}*/
srand((unsigned)time(NULL));
btree_node* node = T.root;
printf("请输入要查询的元素:\n");
scanf("%d", &x);
int pos=btree_search(node,x);
if (pos == -1)
printf("此元素不存在\n");
else
printf("此元素位于它所在节点的第%d个位置上\n", pos+1);
node = T.root;
printf("请输入要删除的元素:\n");
scanf("%d", &x);
if (!btree_delete(&T, x))
printf("删除成功\n"), btree_print(&T,T.root,x);
else
printf("删除失败,不存在该元素\n");
}
b+树
#include <time.h>
#include <iostream>
#include <queue>
#include <string>
#include<algorithm>
using namespace std;
#define M 2//m*2=key数,m*2+1=值;
//插入满格灌,删除一个节点不能少于(M+1)/2,若zhi为5,不能少于2
string key_words[1001];//5阶树,最多4个关键字
class Inter_Node;
class Node
{
public:
Node();
virtual ~Node();
Node* GetBrother(int& flag);
Inter_Node* Parent;
int key[M * 2];//4
int count;
int isLeaf;
void Print();
};
Node::~Node() {}
class Inter_Node : public Node
{
public:
Inter_Node();
virtual ~Inter_Node();//虚函数声明定义
bool Insert(int value, Node* pNode);
bool Delete(int value);
int Split(Inter_Node* pNode, int key);//分裂
bool Merge(Inter_Node* pNode);
bool Slib(Inter_Node* pNode);
Node* Child[M * 2 + 1];//5个查找路径
};
Inter_Node::~Inter_Node()
{
for (int i = 0; i < M * 2 + 1; i++)
Child[i] = NULL;
}
//叶子结点
class Leaf_Node : public Node
{
public:
Leaf_Node();
virtual ~Leaf_Node();
bool Insert(int value);
bool Delete(int value);
int Split(Leaf_Node* pNode);
bool Merge(Leaf_Node* pNode);
Leaf_Node* Pre_Node;
Leaf_Node* Next_Node;
};
Leaf_Node::~Leaf_Node() {}
//B+树
class Bplus
{
public:
Bplus();
virtual ~Bplus();
bool Search(int data, string& sPath);
bool Insert(int data);
bool Delete(int data);
void Print();
protected:
Leaf_Node* Find(int data);
bool Add_Node(Inter_Node* pNode, int key, Node* New_Node);
bool Remove_Node(Inter_Node* pNode, int key);
Node* Root;
};
Bplus::~Bplus() {}
//结点创建对象
Node::Node()
{
isLeaf = true;
count = 0;
Parent = NULL;
}
//叶子结点创建对象
Leaf_Node::Leaf_Node()
{
isLeaf = true;
Pre_Node = NULL;
Next_Node = NULL;
}
//中间结点创建对象
Inter_Node::Inter_Node()
{
isLeaf = false;
for (int i = 0; i < M * 2 + 1; i++)
Child[i] = NULL;
}
//Bplus创建对象
Bplus::Bplus()
{
Root = NULL;
}
//结点查找兄弟结点
Node* Node::GetBrother(int& flag)
{
if (NULL == Parent)
return NULL;
Node* p = NULL;
for (int i = 0; i <= Parent->count; i++)
{
if (Parent->Child[i] == this)
{
if (i == Parent->count)
{
p = Parent->Child[i - 1];//左兄弟 flag=1
flag = 1;
}
else
{
p = Parent->Child[i + 1];//右兄弟 flag=2
flag = 2;
}
}
}
return p;
}
//结点输出
void Node::Print()
{
for (int i = 0; i < count; i++)
{
cout << "(" << key[i] << "," << key_words[key[i]] << ") ";
if (i >= count - 1)
cout << " | ";
}
}
//叶子结点的分裂
int Leaf_Node::Split(Leaf_Node* p)
{
int j = 0;
for (int i = M; i < M * 2; i++, j++)//把值copy到新节点
p->key[j] = this->key[i];//this为old node
this->count = this->count - j;
p->count = j;
return p->key[0];
}
//叶子结点删除
bool Leaf_Node::Delete(int value)
{
bool found = false;
int i = 0;
for (; i < count; i++)
{
if (value == key[i])
{
found = true;
break;
}
}
if (false == found)
return false;
int j = i;
for (; j < count - 1; j++)
key[j] = key[j + 1];
key[j] = 0;
count--;
return true;
}
//叶子结点的插入
bool Leaf_Node::Insert(int value)
{
int i = 0;
for (; (value > key[i]) && (i < count); i++)//按顺序
{
}
for (int j = count; j > i; j--)//移动,找到应该插入的关键字位置
key[j] = key[j - 1];
key[i] = value;//插入关键字
count++;
return true;
}
//叶结点查找
Leaf_Node* Bplus::Find(int data)//data为关键字
{
int i = 0;
Node* p = Root; //?????bplus的跟
Inter_Node* q; //?м???
while (NULL != p)
{
if (p->isLeaf) //????????????
break;
for (i = 0; i < p->count; i++) //??????p??key?????p不是叶子,循环至count的节点
{
if (data < p->key[i])
break;
}
q = (Inter_Node*)p;
p = q->Child[i];
}
return (Leaf_Node*)p;//把根return,如果跟为空,第一个插入函数生成的节点即为根
}
//叶子结点,合并叶子结点
bool Leaf_Node::Merge(Leaf_Node* p)
{
if (this->count + p->count > M * 2)//如果加在一起格满说明不需要合并
return false;
for (int i = 0; i < p->count; i++)//否则将oldnode的关键字都插入到bro里
this->Insert(p->key[i]);
return true;
}
//中间结点Merge合并
bool Inter_Node::Merge(Inter_Node* p)
{
key[count] = p->Child[0]->key[0];
count++;
Child[count] = p->Child[0];
for (int i = 0; i < p->count; i++)
{
key[count] = p->key[i];
count++;
Child[count] = p->Child[i + 1];
}
return true;
}
//中间结点插入
bool Inter_Node::Insert(int value, Node* New)
{
int i = 0;
for (; (i < count) && (value > key[i]); i++)//i指向key要插入的位置
{
}
for (int j = count; j > i; j--)//挪动倒地方
key[j] = key[j - 1];
for (int j = count + 1; j > i + 1; j--)//父亲key值改变,孩子移动;
Child[j] = Child[j - 1];
key[i] = value;//关键字传到父亲节点
Child[i + 1] = New;//newnode放到该放的位置
New->Parent = this;
count++;
return true;
}
//中间结点分裂
int Inter_Node::Split(Inter_Node* p, int k)
{
int i = 0, j = 0;
if ((k > this->key[M - 1]) && (k < this->key[M]))//分裂的地方在中间
{
for (i = M; i < M * 2; i++, j++)
p->key[j] = this->key[i];//拷贝后面值进brother
j = 1;
for (i = M + 1; i <= M * 2; i++, j++)
{
this->Child[i]->Parent = p;//孩子跟着往后移动
p->Child[j] = this->Child[i];
}
this->count = M;//关键子数量各位一半
p->count = M;
return k;
}
int pos = k < this->key[M - 1] ? (M - 1) : M;//看k大小和中间-1比较,定位在前面还是在后面节点
k = this->key[pos];//pos为分裂点,定位为前还是后分裂点,最后肯定为中间值
j = 0;
for (i = pos + 1; i < M * 2; i++, j++)//前节点考后节点,从插入的位置分,插入以后的放到新节点
p->key[j] = this->key[i];
j = 0;
for (i = pos + 1; i <= M * 2; i++, j++)//将孩子送给兄弟
{
this->Child[i]->Parent = p;
p->Child[j] = this->Child[i];
}
this->count = pos;
p->count = M * 2 - pos - 1;
return k;
}
//中间结点删除
bool Inter_Node::Delete(int k)
{
int i = 0;
for (; (k >= key[i]) && (i < count); i++)
{
}
for (int j = i - 1; j < count - 1; j++)
key[j] = key[j + 1];
k = i;
for (; k < count; k++)
{
Child[k] = Child[k + 1];
}
Child[k] = NULL;
count--;
return true;
}
//中间结点
bool Inter_Node::Slib(Inter_Node* p)
{
int i, j;
if (p->key[0] < this->key[0])
{
for (i = count; i > 0; i--)
key[i] = key[i - 1];
for (j = count + 1; j > 0; j--)
Child[j] = Child[j - 1];
key[0] = Child[0]->key[0];
Child[0] = p->Child[p->count];
}
else
{
key[count] = p->Child[0]->key[0];
Child[count + 1] = p->Child[0];
for (i = 1; i < p->count - 1; i++)
p->key[i - 1] = p->key[i];
for (j = 0; j < p->count - 1; j++)
p->Child[j] = p->Child[j + 1];
}
this->count++;
p->count--;
return true;
}
//B+树添加结点
bool Bplus::Add_Node(Inter_Node* p, int k, Node* New_Node)
{
if (NULL == p || p->isLeaf)
return false;
if (p->count < M * 2)//父亲不满
return p->Insert(k, New_Node);
Inter_Node* Brother = new Inter_Node;
//叶子节点满,父节点也满分裂情况
int NewKey = p->Split(Brother, k);//NewKey为需要提取并插入到root节点的值
//确定需要插入的关键字,是插入到分裂节点的哪个位置
if (p->count < Brother->count)
{
p->Insert(k, New_Node);
}
else if (p->count > Brother->count)
{
Brother->Insert(k, New_Node);
}
else
{
Brother->Child[0] = New_Node;
New_Node->Parent = Brother;
}
Inter_Node* parent = (Inter_Node*)(p->Parent);
if (NULL == parent)
{
parent = new Inter_Node();
parent->Child[0] = p;
parent->key[0] = NewKey;//newkey为分裂传回,为插入的中间值
parent->Child[1] = Brother;
p->Parent = parent;
Brother->Parent = parent;
parent->count = 1;
Root = parent;
return true;
}
return Add_Node(parent, NewKey, Brother);
}
//B+树查找data
bool Bplus::Search(int data, string& sPath)
{
int i = 0;
sPath = "查找路径为: ";
Node* p = Root;
if (NULL == p)
return false;
Inter_Node* q;
while (NULL != p)
{
if (p->isLeaf)
break;
for (i = 0; (i < p->count) && (data >= p->key[i]); i++)
{
}
int k = i > 0 ? i - 1 : i;
sPath += to_string(p->key[k]);
sPath += "-->";
q = (Inter_Node*)p;
p = q->Child[i];
}
if (NULL == p)
return false;
sPath += to_string(p->key[0]);
bool found = false;
for (i = 0; i < p->count; i++)
{
if (data == p->key[i])
found = true;
//sPath += to_string(p->key[i]);
//sPath += "-->";
}
if (found)
{
sPath += " OK";
}
else
{
sPath += " FAIL";
}
return found;
}
//B+树的插入
bool Bplus::Insert(int data) //data为插入的关键字
{
string a;
if (true == Search(data, a))//查找要插入的值
return false;
Leaf_Node* Old_Node = Find(data);//找到需要插入的叶子节点定义为oldnode
if (NULL == Old_Node)
{
Old_Node = new Leaf_Node;//树为空
Root = Old_Node;
}
if (Old_Node->count < M * 2) {//有空间插入,直接插进去并返回
return Old_Node->Insert(data);
}
Leaf_Node* New_Node = new Leaf_Node;//即将分裂
int k = Old_Node->Split(New_Node);//k为新节点第一个关键子
Leaf_Node* OldNext = Old_Node->Next_Node;
Old_Node->Next_Node = New_Node;//相邻叶子节点相连
New_Node->Next_Node = OldNext;
New_Node->Pre_Node = Old_Node;
if (NULL != OldNext)
OldNext->Pre_Node = New_Node;
if (data < k)//小于newnode key[0],插前面,否则插后面
{
Old_Node->Insert(data);
}
else
{
New_Node->Insert(data);
}
Inter_Node* parent = (Inter_Node*)(Old_Node->Parent);
if (NULL == parent)//初始化parent,若没有父结点,新建一个
{
Inter_Node* New_Root = new Inter_Node;
New_Root->Child[0] = Old_Node;
New_Root->key[0] = k;
New_Root->Child[1] = New_Node;
Old_Node->Parent = New_Root;
New_Node->Parent = New_Root;
New_Root->count = 1;
Root = New_Root;
return true;
}
return Add_Node(parent, k, New_Node);//向父亲里插值或者分裂父亲建立新的节点
}
//B+树的删除
bool Bplus::Delete(int data)
{
Leaf_Node* Old_Node = Find(data); //查找数据
if (NULL == Old_Node)//树为空
return false;
if (false == Old_Node->Delete(data)) //删除
return false;
Inter_Node* parent = (Inter_Node*)(Old_Node->Parent);
if (NULL == parent)
{
if (0 == Old_Node->count)//将整棵树删掉,没父亲没key
{
delete Old_Node;
Root = NULL;
}
return true;
}
if (Old_Node->count >= M)
{
for (int i = 0; (i < parent->count) && (data >= parent->key[i]); i++)
{
if (parent->key[i] == data)//如果要删除的key比父亲索引他的值要大就直接删除,如果相等,就给父亲一个新索引
parent->key[i] = Old_Node->key[0];
}
return true;
}
//不满足规格,要合并或借值
int flag = 1;
Leaf_Node* Brother = (Leaf_Node*)(Old_Node->GetBrother(flag));
int NewData = 0;
if (Brother->count > M)//借值
{
if (1 == flag)//左兄弟
{
NewData = Brother->key[Brother->count - 1];//要被借走的数据
}
else//右兄弟
{
NewData = Brother->key[0];
}
Old_Node->Insert(NewData);
Brother->Delete(NewData);
//替换parent中的key值
if (1 == flag)
{
for (int i = 0; i <= parent->count; i++)//向左兄弟借值
{
if (parent->Child[i] == Old_Node && i > 0)
parent->key[i - 1] = Old_Node->key[0];
}
}
else
{
for (int i = 0; i <= parent->count; i++)//向右兄弟借值
{
if (parent->Child[i] == Old_Node && i > 0)
parent->key[i - 1] = Old_Node->key[0];
if (parent->Child[i] == Brother && i > 1)
parent->key[i - 1] = Brother->key[0];
}
}
return true;
}
int NewKey = 0;
if (1 == flag)//无法借值,合并
{
Brother->Merge(Old_Node);
NewKey = Old_Node->key[0];//标记要删除的父亲里的key
Leaf_Node* OldNext = Old_Node->Next_Node;//接入后面兄弟
Brother->Next_Node = OldNext;
if (NULL != OldNext)
OldNext->Pre_Node = Brother;
delete Old_Node;
}
else
{
Old_Node->Merge(Brother);
NewKey = Brother->key[0];
Leaf_Node* OldNext = Brother->Next_Node;
Old_Node->Next_Node = OldNext;
if (NULL != OldNext)
OldNext->Pre_Node = Old_Node;
delete Brother;
}
return Remove_Node(parent, NewKey);//移除parent或者移除parent中关键字;
}
//Bplus 移除结点
bool Bplus::Remove_Node(Inter_Node* p, int k)
{
if (false == p->Delete(k))
{
return false;
}
Inter_Node* parent = (Inter_Node*)(p->Parent);
if (NULL == parent)
{
if (0 == p->count)
{
Root = p->Child[0];
delete p;
}
return true;
}
if (p->count >= M)//父亲不合并
{
//删掉parent中的关键字
for (int i = 0; (i < parent->count) && (k >= parent->key[i]); i++)
{
if (parent->key[i] == k)//看父亲的parent里有没有要删除的关键字,有就更新索引
parent->key[i] = p->key[0];
}
return true;
}
//父亲合并
int flag = 1;
Inter_Node* Brother = (Inter_Node*)(p->GetBrother(flag));
if (Brother->count > M)//父亲借值
{
p->Slib(Brother);
if (1 == flag)
{
for (int i = 0; i <= parent->count; i++)
{
if (parent->Child[i] == p && i > 0)
parent->key[i - 1] = p->key[0];
}
}
else
{
for (int i = 0; i <= parent->count; i++)
{
if (parent->Child[i] == p && i > 0)
parent->key[i - 1] = p->key[0];
if (parent->Child[i] == Brother && i > 0)
parent->key[i - 1] = Brother->key[0];
}
}
return true;
}
//兄弟借值
int NewKey = 0;
if (1 == flag)
{
Brother->Merge(p);
NewKey = p->key[0];
delete p;
}
else
{
p->Merge(Brother);
NewKey = Brother->key[0];
delete Brother;
}
return Remove_Node(parent, NewKey);
}
//Bplus输出
void Bplus::Print()
{
Node* p = Root;
if (NULL == p)
return;
Inter_Node* a;
int H = 0;
queue<Node*> q;
queue<int> h;
q.push(p);
h.push(1);
while (!q.empty())
{
p = q.front();
if (H != h.front())
{
cout << endl;
cout << H << endl;
H = h.front();
}
q.pop();
h.pop();
p->Print();
if (NULL != p && !p->isLeaf)
{
a = (Inter_Node*)p;
for (int i = 0; i <= p->count; i++)
{
q.push(a->Child[i]);
h.push(H + 1);
}
}
}
}
//测试:test1 建立B+tree
void test1(Bplus* bplus, int count)//count为想要几个节点,返回值建一个树
{
srand((unsigned)time(NULL));
//随机种子
cout << " 插入数据: ";
for (int i = 1; i <= count; i++)//
{
//int x = i;
int x = rand() % 1000 + 1;//随机生成x
key_words[x] = " ";
for (int i = 0; i < 2; i++)
{
int y = rand() % 26 + 65;//生成一个随机数
int z = rand() % 26 + 97;
key_words[x] += char(y);
key_words[x] += char(z);
}//生成四个字符的数据
cout << "[" << x << " "
<< "," << key_words[x] << "]" << " ";
bplus->Insert(x);//x=key
}
cout << "B+树建立suceess!" << endl;
cout << endl;
}
//测试:test2查询
void test2(Bplus* bplus, int data)
{
string sPath;
bplus->Search(data, sPath);
cout << sPath;
cout << endl;
}
//测试:test3插入
void test3(Bplus* bplus, int data, string s)
{
bool success = bplus->Insert(data);
key_words[data] = s;
if (true == success)
{
cout << "OK" << endl;
}
else
{
cout << "FAIL" << endl;
}
cout << endl;
}
//测试:test4删除
void test4(Bplus* bplus, int data)
{
bool success = bplus->Delete(data);
if (true == success)
{
cout << "成功" << endl;
}
else
{
cout << "错误" << endl;
}
cout << endl;
}
//测试:test5打印
void test5(Bplus* bplus)
{
bplus->Print();
cout << endl;
}
//测试:test6修改
void test6(Bplus* bplus, int i, string j, int k, string l)
{
if (i == k)
{
key_words[i] = l;
}
else
{
//i != j
//删除(i , j );
bplus->Delete(i);
//插入(k , l )
bplus->Insert(k);
//初始化结点内容
key_words[k] = l;
}
cout << endl;
}
//主函数
int main()
{
Bplus* bplus = new Bplus();
int x = 1;
int y = 0;
int z;
string s = " ";
int i, k;
string j = " ";
string l = " ";
while (0 != x)
{
cout << "1.请问需要多少个节点的B+tree" << endl;
cout << "2.需要查询 " << endl;
cout << "3.需要插入内容 " << endl;
cout << "4.需要删除内容" << endl;
cout << "5.需要显示B+树形状" << endl;
cout << "6.需要修改内容" << endl;
cout << " \n";
cin >> x;
switch (x)
{
case 1:
cout << "请输入需要多少个结点:";
cin >> y;
test1(bplus, y);
break;
case 2:
cout << "要查询的关键值key A:";
srand((unsigned)time(NULL));
y = rand()%1000;
printf("%d\n", y);
test2(bplus, y);
break;
case 3:
cout << "要插入的关键值key A和B:";
srand((unsigned)time(NULL));
y = rand()%1000;
z = rand();
while (z)
{
s += char(z % 10 + 'A');
z /= 10;
}
cout << y << " " << s << endl;
test3(bplus, y, s);
s = "";
break;
case 4:
cout << "请输入要删除的关键值key A:";
srand((unsigned)time(NULL));
y = rand()%1000;
cout << y << endl;
test4(bplus, y);
break;
case 5:
test5(bplus);
break;
case 6:
cout << "请输入要删除的A和B:";
cin >> i >> j;
cout << "请输入要插入的A和B:";
cin >> k >> l;
test6(bplus, i, j, k, l);
break;
default:
delete bplus;
return 0;
break;
}
}
return 0;
}