[数据结构]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 Hash索引和B-Tree索引区别(Comparison of B-Tree and Hash Indexes)