[数据结构]B-Tree

Posted yccy1230

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[数据结构]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;



以上是关于[数据结构]B-Tree的主要内容,如果未能解决你的问题,请参考以下文章

Mysql索引原理B-Tree, B+Tree

B-tree

Mysql B-Tree和B+Tree索引

Mysql Hash索引和B-Tree索引区别(Comparison of B-Tree and Hash Indexes)

[数据结构]B-Tree

Python中有B-Tree数据库或框架吗?