//B-Tree.h
enum Error_code { not_present, duplicate_error, overflow, success };
template<class Entry,int order>
struct B_node
{
int count; //记录关键码个数
Entry data[order - 1]; //存储关键码
B_node<Entry, order> *branch[order]; //存储branch指针
B_node();
};
template<class Entry, int order>
inline B_node<Entry, order>::B_node()
{
count = 0;
}
template<class Entry, int order>
class B_tree
{
public:
B_tree();
Error_code search_tree(Entry &target);
Error_code insert(const Entry &target);
Error_code remove(const Entry &target);
private:
B_node<Entry, order> *root;
//SEARCH:
Error_code recursive_search_tree(B_node<Entry, order> *current, Entry &target);
Error_code search_node(B_node<Entry, order> *current, const Entry&target, int &position);
//INSERT:
Error_code push_down(B_node<Entry, order> *current, const Entry &new_entry,
Entry &median, B_node<Entry, order> * &right_branch);
void push_in(B_node<Entry, order> *current,const Entry &entry,
B_node<Entry, order> *right_branch, int position);
void split_node(B_node<Entry, order> *current, const Entry &extra_entry,
B_node<Entry, order> *extra_branch,int position,
B_node<Entry, order> * &right_half, Entry &median);
//REMOVE:
Error_code recursive_remove(B_node<Entry, order> *current, const Entry &target);
void remove_data(B_node<Entry, order> *current, int position);
void copy_in_predecessor(B_node<Entry, order> *current, int position);
void restore(B_node<Entry, order> *current, int position);
void move_left(B_node<Entry, order> *current, int position);
void move_right(B_node<Entry, order> *current, int position);
void combine(B_node<Entry, order> *current, int position);
};
//B-Tree.cpp
#include"B_tree.h"
#include<iostream>
using namespace std;
template<class Entry, int order>
B_tree<Entry, order>::B_tree()
{
root = NULL;
}
template<class Entry, int order>
Error_code B_tree<Entry, order>::search_tree(Entry & target)
{
return recursive_search_tree(root, target);
}
template<class Entry, int order>
Error_code B_tree<Entry, order>::insert(const Entry & target)
{
Entry median;
B_node<Entry, order> *right_branch, *new_root;
Error_code result = push_down(root, target, median, right_branch);
if (result == overflow) {
new_root = new B_node<Entry, order>;
new_root->count = 1;
new_root->data[0] = median;
new_root->branch[0] = root;
new_root->branch[1] = right_branch;
root = new_root;
result = success;
}
return result;
}
template<class Entry, int order>
Error_code B_tree<Entry, order>::remove(const Entry & target)
{
Error_code result = recursive_remove(root, target);
if (root != NULL&&root->count == 0) {
B_node<Entry, order> *tmp = root;
root = root->branch[0];
delete tmp;
}
return result;
}
template<class Entry, int order>
Error_code B_tree<Entry, order>::recursive_search_tree(B_node<Entry, order>* current, Entry & target)
{
Error_code result = not_present;
int position = 0;
if (current != NULL) {
result = search_node(current, target, position);
if (result == not_present)
result = recursive_search_tree(current->branch[position], target);
else
target = current->data[position];
}
return result;
}
template<class Entry, int order>
Error_code B_tree<Entry, order>::search_node(B_node<Entry, order>* current, const Entry & target, int & position)
{
/*查找当前节点是否存在target,若存在返回position,不存在,返回target应该存储的branch的位置*/
position = 0;
while (current->count > position&¤t->data[position] < target)
position++;
if (position < current->count&¤t->data[position] == target)
return success;
else return not_present;
}
template<class Entry, int order>
Error_code B_tree<Entry, order>::push_down(B_node<Entry, order>* current, const Entry & new_entry, Entry & median, B_node<Entry, order>*& right_branch)
{
Error_code result;
int position;
if (current == NULL) {
median = new_entry;
right_branch = NULL;
result = overflow;
}
else {
if (search_node(current, new_entry, position) == success)return duplicate_error;
Entry extra_entry;
B_node<Entry, order> *extra_branch;
result = push_down(current->branch[position], new_entry, extra_entry, extra_branch);//转换为对branch的插入
if (result == overflow) {
if (current->count < order - 1) {//当前节点未达到饱和
result = success;
push_in(current, extra_entry, extra_branch, position);
}
else split_node(current, extra_entry, extra_branch, position, right_branch, median);//饱和分裂
}
}
return result;
}
template<class Entry, int order>
void B_tree<Entry, order>::push_in(B_node<Entry, order>* current, const Entry & entry, B_node<Entry, order>* right_branch, int position)
{ /*在给定position处插入data*/
for (int i = current->count; i > position; i--) {
current->data[i] = current->data[i - 1];
current->branch[i + 1] = current->branch[i];
}
current->data[position] = entry;
current->branch[position + 1] = right_branch;
current->count++;
}
template<class Entry, int order>
void B_tree<Entry, order>::split_node(B_node<Entry, order>* current, const Entry & extra_entry, B_node<Entry, order>* extra_branch, int position, B_node<Entry, order>*& right_half, Entry & median)
{
right_half = new B_node<Entry, order>;
int mid = order / 2;
if (position <= mid) {//待插入节点位于一半的左边
for (int i = mid; i < order - 1; i++) {
right_half->data[i-mid] = current->data[i];
right_half->branch[i - mid + 1] = current->branch[i + 1];
}
current->count = mid;
right_half->count = order - mid - 1;
push_in(current, extra_entry, extra_branch, position);
//在current的position处正常插入data
}
else {//待插入节点位于一半的右边
mid++;
for (int i = mid; i < order - 1; i++) {
right_half->data[i - mid] = current->data[i];
right_half->branch[i - mid + 1] = current->branch[i + 1];
}
current->count = mid;
right_half->count = order - mid - 1;
push_in(right_half, extra_entry, extra_branch, position-mid);
//在right-half的position-mid处正常插入data
}
median = current->data[current->count - 1];//remove median
right_half->branch[0] = current->branch[current->count];//move median‘s branch to right-half
current->count--;
}
template<class Entry, int order>
Error_code B_tree<Entry, order>::recursive_remove(B_node<Entry, order>* current, const Entry & target)
{
Error_code result;
int position;
if (current == NULL)return not_present;
else {
if (search_node(current, target, position) == success) {
result = success;
if (current->branch[position] != NULL) {//非叶子节点
copy_in_predecessor(current, position);//替换前驱
recursive_remove(current->branch[position], current->data[position]);//递归删除空节点
}
else remove_data(current, position);//叶子节点直接删除
}
else result = recursive_remove(current->branch[position], target);
if (current->branch[position] != NULL)
if (current->branch[position]->count < (order - 1) / 2)
restore(current, position);
}
return result;
}
template<class Entry, int order>
void B_tree<Entry, order>::remove_data(B_node<Entry, order>* current, int position)
{
for (int i = position; i < current->count - 1; i++)
current->data[i] =current->data[i + 1];
current->count--;
}
template<class Entry, int order>
void B_tree<Entry, order>::copy_in_predecessor(B_node<Entry, order>* current, int position)
{/*找到前驱,并将当前节点的data修改为前驱的data值*/
B_node<Entry, order> *tmp = current->branch[position];
while (tmp->branch[tmp->count] != NULL)
tmp = tmp->branch[tmp->count];
current->data[position] = tmp->data[tmp->count - 1];
}
template<class Entry, int order>
void B_tree<Entry, order>::restore(B_node<Entry, order>* current, int position)
{
/*解决删除后data数量不满足B-Tree定义的情况*/
if (position == current->count) { //最右侧情况
if (current->branch[position - 1]->count > (order - 1) / 2)
move_right(current, position - 1);
else
combine(current, position);
}
else if (position == 0) { //最左侧情况
if (current->branch[1]->count > (order - 1) / 2)
move_left(current, 1);
else
combine(current, 1);
}
else { //一般情况
if (current->branch[position - 1]->count > (order - 1) / 2)
move_right(current, position - 1);
else if (current->branch[position + 1]->count > (order - 1) / 2)
move_left(current, position + 1);
else
combine(current, position);
}
}
template<class Entry, int order>
void B_tree<Entry, order>::move_left(B_node<Entry, order>* current, int position)
{
B_node<Entry, order> *left_branch = current->branch[position - 1];
B_node<Entry, order> *right_branch = current->branch[position];
left_branch->data[left_branch->count] = current->data[position - 1];
left_branch->branch[++left_branch->count] = right_branch->branch[0];
current->data[position - 1] = right_branch->data[0];
right_branch->count--;
for (int i = 0; i < right_branch->count; i++) {
right_branch->data[i] = right_branch->data[i + 1];
right_branch->branch[i] = right_branch->branch[i + 1];
}
right_branch->branch[right_branch->count] = right_branch->branch[right_branch->count + 1];
}
template<class Entry, int order>
void B_tree<Entry, order>::move_right(B_node<Entry, order>* current, int position)
{
B_node<Entry, order> *left_branch = current->branch[position];
B_node<Entry, order> *right_branch = current->branch[position+1];
right_branch->branch[right_branch->count + 1] = right_branch->branch[right_branch->count];
for (int i = right_branch->count; i > 0; i--) {
right_branch->data[i] = right_branch->data[i - 1];
right_branch->branch[i] = right_branch->branch[i - 1];
}
right_branch->count++;
right_branch->data[0] = current->data[position];
right_branch->branch[0] = left_branch->branch[left_branch->count--];
current->data[position] = left_branch->data[left_branch->count];
}
template<class Entry, int order>
void B_tree<Entry, order>::combine(B_node<Entry, order>* current, int position)
{
B_node<Entry, order> *left_branch = current->branch[position - 1];
B_node<Entry, order> *right_branch = current->branch[position];
left_branch->data[left_branch->count] = current->data[position - 1];
left_branch->branch[++left_branch->count] = right_branch->branch[0];
for (int i = 0; i < right_branch->count; i++) {
left_branch->data[left_branch->count] = right_branch->data[i];
left_branch->branch[++left_branch->count] = right_branch->branch[i + 1];
}
current->count--;
for (int i = position - 1; i < current->count; i++) {
current->data[i] = current->data[i + 1];
current->branch[i + 1] = current->branch[i + 2];
}
delete right_branch;
}