[数据结构]B-Tree

//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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值