//高大上
看到一篇相关的好文章,引用下:http://www.cnblogs.com/leoo2sk/archive/2011/07/10/mysql-index.html 。相当滴不错,备忘下。
在这篇文章中http://blog.csdn.net/weege/article/details/6526512介绍了B-tree/B+tree/B*tree,并且介绍了B-tree的查找,插入,删除操作。现在重新认识下B-TREE(温故而知新嘛~,确实如此。自己在写代码中会体会到,B-tree的操作出现的条件相对其他树比较复杂,调试也是一个理通思路的过程。)
B-tree又叫平衡多路查找树。一棵m阶的B-tree (m叉树)的特性如下:
(其中ceil(x)是一个取上限的函数)
1) 树中每个结点至多有m个孩子;
2) 除根结点和叶子结点外,其它每个结点至少有有ceil(m / 2)个孩子;
3) 若根结点不是叶子结点,则至少有2个孩子(特殊情况:没有孩子的根结点,即根结点为叶子结点,整棵树只有一个根节点);
4) 所有叶子结点都出现在同一层,叶子结点不包含任何关键字信息(可以看做是外部结点或查询失败的结点,实际上这些结点不存在,指向这些结点的指针都为null)(PS:这种说法是按照严蔚敏那本教材给出的,具体操作不同而定,下面的实现中的叶子结点是树的终端结点,即没有孩子的结点);
5) 每个非终端结点中包含有n个关键字信息: (n,P0,K1,P1,K2,P2,......,Kn,Pn)。其中:
a) Ki (i=1...n)为关键字,且关键字按顺序排序K(i-1)< Ki。
b) Pi为指向子树根的接点,且指针P(i-1)指向子树种所有结点的关键字均小于Ki,但都大于K(i-1)。
c) 关键字的个数n必须满足: ceil(m / 2)-1 <= n <= m-1。
具体代码实现如下:(这里只是给出了简单的B-Tree结构,在内存中的数据操作。具体详情见代码吧~!)
头文件:(提供B-Tree基本的操作接口)
-
-
-
-
-
-
-
-
-
- #ifndef BTREE_H
- #define BTREE_H
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
-
-
- #define BTree_D 2
- #define ORDER (BTree_D * 2) //定义为4阶B-tree,2-3-4树。(偶序)
-
-
- typedef int KeyType;
- typedef struct BTNode{
- int keynum;
- KeyType key[ORDER-1];
- struct BTNode* child[ORDER];
- char isLeaf;
- }BTNode;
-
- typedef BTNode* BTree;
-
-
- void BTree_create(BTree* tree, const KeyType* data, int length);
-
-
- void BTree_destroy(BTree* tree);
-
-
- void BTree_insert(BTree* tree, KeyType key);
-
-
- void BTree_remove(BTree* tree, KeyType key);
-
-
- void BTree_print(const BTree tree, int layer);
-
-
-
-
- BTNode* BTree_search(const BTree tree, int key, int* pos);
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif
源文件:(提供B-Tree基本的基本操作的实现)
-
-
-
-
-
-
-
-
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <assert.h>
- #include "btree.h"
-
-
- #define cmp(a, b) ( ( ((a)-(b)) >= (0) ) ? (1) : (0) ) //比较a,b大小
- #define DEBUG_BTREE
-
-
-
- void disk_write(BTNode* node)
- {
- int i;
-
- printf("向磁盘写入节点");
- for(i=0;i<ORDER-1;i++){
- printf("%c",node->key[i]);
- }
- printf("\n");
- }
-
-
- void disk_read(BTNode** node)
- {
- int i;
-
- printf("向磁盘读取节点");
- for(i=0;i<ORDER-1;i++){
- printf("%c",(*node)->key[i]);
- }
- printf("\n");
- }
-
-
- void BTree_print(const BTree tree, int layer)
- {
- int i;
- BTNode* node = tree;
-
- if (node) {
- printf("第 %d 层, %d node : ", layer, node->keynum);
-
-
- for (i = 0; i < ORDER-1; ++i) {
-
- printf("%c ", node->key[i]);
- }
-
- printf("\n");
-
- ++layer;
- for (i = 0 ; i <= node->keynum; i++) {
- if (node->child[i]) {
- BTree_print(node->child[i], layer);
- }
- }
- }
- else {
- printf("树为空。\n");
- }
- }
-
-
- int binarySearch(BTNode* node, int low, int high, KeyType Fkey)
- {
- int mid;
- while (low<=high)
- {
- mid = low + (high-low)/2;
- if (Fkey<node->key[mid])
- {
- high = mid-1;
- }
- if (Fkey>node->key[mid])
- {
- low = mid+1;
- }
- if (Fkey==node->key[mid])
- {
- return mid;
- }
- }
- return -1;
- }
-
-
-
-
-
-
-
-
- void BTree_split_child(BTNode* parent, int index, BTNode* node)
- {
- int i;
- BTNode* newNode;
- #ifdef DEBUG_BTREE
- printf("BTree_split_child!\n");
- #endif
- assert(parent && node);
-
-
-
- newNode = (BTNode*)calloc(sizeof(BTNode), 1);
- if (!newNode) {
- printf("Error! out of memory!\n");
- return;
- }
-
- newNode->isLeaf = node->isLeaf;
- newNode->keynum = BTree_D - 1;
-
-
- for (i = 0; i < newNode->keynum; ++i){
- newNode->key[i] = node->key[BTree_D + i];
- node->key[BTree_D + i] = 0;
- }
-
-
- if (!node->isLeaf) {
- for (i = 0; i < BTree_D; i++) {
- newNode->child[i] = node->child[BTree_D + i];
- node->child[BTree_D + i] = NULL;
- }
- }
-
-
- node->keynum = BTree_D - 1;
-
-
- for (i = parent->keynum; i > index; --i) {
- parent->child[i + 1] = parent->child[i];
- }
-
- parent->child[index + 1] = newNode;
-
- for (i = parent->keynum - 1; i >= index; --i) {
- parent->key[i + 1] = parent->key[i];
- }
-
- parent->key[index] = node->key[BTree_D - 1];
- ++parent->keynum;
-
- node->key[BTree_D - 1] = 0;
-
-
- disk_write(parent);
- disk_write(newNode);
- disk_write(node);
- }
-
- void BTree_insert_nonfull(BTNode* node, KeyType key)
- {
- int i;
- assert(node);
-
-
- if (node->isLeaf) {
- i = node->keynum - 1;
- while (i >= 0 && key < node->key[i]) {
- node->key[i + 1] = node->key[i];
- --i;
- }
-
- node->key[i + 1] = key;
- ++node->keynum;
-
-
- disk_write(node);
- }
-
-
- else {
-
- i = node->keynum - 1;
- while (i >= 0 && key < node->key[i]) {
- --i;
- }
-
- ++i;
-
-
- disk_read(&node->child[i]);
-
-
- if (node->child[i]->keynum == (ORDER-1)) {
- BTree_split_child(node, i, node->child[i]);
-
- if (key > node->key[i]) {
- ++i;
- }
- }
- BTree_insert_nonfull(node->child[i], key);
- }
- }
-
- void BTree_insert(BTree* tree, KeyType key)
- {
- BTNode* node;
- BTNode* root = *tree;
-
- #ifdef DEBUG_BTREE
- printf("BTree_insert:\n");
- #endif
-
- if (NULL == root) {
- root = (BTNode*)calloc(sizeof(BTNode), 1);
- if (!root) {
- printf("Error! out of memory!\n");
- return;
- }
- root->isLeaf = 1;
- root->keynum = 1;
- root->key[0] = key;
-
- *tree = root;
-
-
- disk_write(root);
-
- return;
- }
-
-
- if (root->keynum == (ORDER-1)) {
-
- node = (BTNode*)calloc(sizeof(BTNode), 1);
- if (!node) {
- printf("Error! out of memory!\n");
- return;
- }
-
- *tree = node;
- node->isLeaf = 0;
- node->keynum = 0;
- node->child[0] = root;
-
- BTree_split_child(node, 0, root);
-
- BTree_insert_nonfull(node, key);
- }
-
-
- else {
- BTree_insert_nonfull(root, key);
- }
- }
-
-
-
-
-
-
-
-
-
- void BTree_merge_child(BTree* tree, BTNode* node, int index)
- {
- int i;
- KeyType key;
- BTNode *leftChild, *rightChild;
- #ifdef DEBUG_BTREE
- printf("BTree_merge_child!\n");
- #endif
- assert(tree && node && index >= 0 && index < node->keynum);
-
-
- key = node->key[index];
- leftChild = node->child[index];
- rightChild = node->child[index + 1];
-
- assert(leftChild && leftChild->keynum == BTree_D - 1
- && rightChild && rightChild->keynum == BTree_D - 1);
-
-
- leftChild->key[leftChild->keynum] = key;
- leftChild->child[leftChild->keynum + 1] = rightChild->child[0];
- ++leftChild->keynum;
-
-
- for (i = 0; i < rightChild->keynum; ++i) {
- leftChild->key[leftChild->keynum] = rightChild->key[i];
- leftChild->child[leftChild->keynum + 1] = rightChild->child[i + 1];
- ++leftChild->keynum;
- }
-
-
- for (i = index; i < node->keynum - 1; ++i) {
- node->key[i] = node->key[i + 1];
- node->child[i + 1] = node->child[i + 2];
- }
- node->key[node->keynum - 1] = 0;
- node->child[node->keynum] = NULL;
- --node->keynum;
-
-
- if (node->keynum == 0) {
- if (*tree == node) {
- *tree = leftChild;
- }
-
- free(node);
- node = NULL;
- }
-
- free(rightChild);
- rightChild = NULL;
- }
-
- void BTree_recursive_remove(BTree* tree, KeyType key)
- {
-
-
-
- int i, j, index;
- BTNode *root = *tree;
- BTNode *node = root;
-
- if (!root) {
- printf("Failed to remove %c, it is not in the tree!\n", key);
- return;
- }
-
-
- index = 0;
- while (index < node->keynum && key > node->key[index]) {
- ++index;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if (index < node->keynum && node->key[index] == key) {
- BTNode *leftChild, *rightChild;
- KeyType leftKey, rightKey;
-
- if (node->isLeaf) {
- for (i = index; i < node->keynum-1; ++i) {
- node->key[i] = node->key[i + 1];
-
- }
- node->key[node->keynum-1] = 0;
-
- --node->keynum;
-
- if (node->keynum == 0) {
- assert(node == *tree);
- free(node);
- *tree = NULL;
- }
-
- return;
- }
-
-
-
-
-
- else if (node->child[index]->keynum >= BTree_D) {
- leftChild = node->child[index];
- leftKey = leftChild->key[leftChild->keynum - 1];
- node->key[index] = leftKey;
-
- BTree_recursive_remove(&leftChild, leftKey);
- }
-
-
-
-
- else if (node->child[index + 1]->keynum >= BTree_D) {
- rightChild = node->child[index + 1];
- rightKey = rightChild->key[0];
- node->key[index] = rightKey;
-
- BTree_recursive_remove(&rightChild, rightKey);
- }
-
-
-
-
-
- else if (node->child[index]->keynum == BTree_D - 1
- && node->child[index + 1]->keynum == BTree_D - 1){
- leftChild = node->child[index];
-
- BTree_merge_child(tree, node, index);
-
-
- BTree_recursive_remove(&leftChild, key);
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- else {
- BTNode *leftSibling, *rightSibling, *child;
-
-
- child = node->child[index];
- if (!child) {
- printf("Failed to remove %c, it is not in the tree!\n", key);
- return;
- }
-
- if (child->keynum == BTree_D - 1) {
- leftSibling = NULL;
- rightSibling = NULL;
-
- if (index - 1 >= 0) {
- leftSibling = node->child[index - 1];
- }
-
- if (index + 1 <= node->keynum) {
- rightSibling = node->child[index + 1];
- }
-
-
-
-
- if ((leftSibling && leftSibling->keynum >= BTree_D)
- || (rightSibling && rightSibling->keynum >= BTree_D)) {
- int richR = 0;
- if(rightSibling) richR = 1;
- if(leftSibling && rightSibling) {
- richR = cmp(rightSibling->keynum,leftSibling->keynum);
- }
- if (rightSibling && rightSibling->keynum >= BTree_D && richR) {
-
- child->key[child->keynum] = node->key[index];
- child->child[child->keynum + 1] = rightSibling->child[0];
- ++child->keynum;
-
- node->key[index] = rightSibling->key[0];
-
- for (j = 0; j < rightSibling->keynum - 1; ++j) {
- rightSibling->key[j] = rightSibling->key[j + 1];
- rightSibling->child[j] = rightSibling->child[j + 1];
- }
- rightSibling->key[rightSibling->keynum-1] = 0;
- rightSibling->child[rightSibling->keynum-1] = rightSibling->child[rightSibling->keynum];
- rightSibling->child[rightSibling->keynum] = NULL;
- --rightSibling->keynum;
- }
- else {
- for (j = child->keynum; j > 0; --j) {
- child->key[j] = child->key[j - 1];
- child->child[j + 1] = child->child[j];
- }
- child->child[1] = child->child[0];
- child->child[0] = leftSibling->child[leftSibling->keynum];
- child->key[0] = node->key[index - 1];
- ++child->keynum;
-
- node->key[index - 1] = leftSibling->key[leftSibling->keynum - 1];
-
- leftSibling->key[leftSibling->keynum - 1] = 0;
- leftSibling->child[leftSibling->keynum] = NULL;
-
- --leftSibling->keynum;
- }
- }
-
-
-
-
-
- else if ((!leftSibling || (leftSibling && leftSibling->keynum == BTree_D - 1))
- && (!rightSibling || (rightSibling && rightSibling->keynum == BTree_D - 1))) {
- if (leftSibling && leftSibling->keynum == BTree_D - 1) {
-
- BTree_merge_child(tree, node, index - 1);
-
- child = leftSibling;
- }
-
- else if (rightSibling && rightSibling->keynum == BTree_D - 1) {
-
- BTree_merge_child(tree, node, index);
- }
- }
- }
-
- BTree_recursive_remove(&child, key);
- }
- }
-
- void BTree_remove(BTree* tree, KeyType key)
- {
- #ifdef DEBUG_BTREE
- printf("BTree_remove:\n");
- #endif
- if (*tree==NULL)
- {
- printf("BTree is NULL!\n");
- return;
- }
-
- BTree_recursive_remove(tree, key);
- }
-
-
-
- BTNode* BTree_recursive_search(const BTree tree, KeyType key, int* pos)
- {
- int i = 0;
-
- while (i < tree->keynum && key > tree->key[i]) {
- ++i;
- }
-
-
- if (i < tree->keynum && tree->key[i] == key) {
- *pos = i;
- return tree;
- }
-
-
- if (tree->isLeaf) {
- return NULL;
- }
-
-
-
-
-
- disk_read(&tree->child[i]);
-
-
- return BTree_recursive_search(tree->child[i], key, pos);
- }
-
- BTNode* BTree_search(const BTree tree, KeyType key, int* pos)
- {
- #ifdef DEBUG_BTREE
- printf("BTree_search:\n");
- #endif
- if (!tree) {
- printf("BTree is NULL!\n");
- return NULL;
- }
- *pos = -1;
- return BTree_recursive_search(tree,key,pos);
- }
-
-
- void BTree_create(BTree* tree, const KeyType* data, int length)
- {
- int i, pos = -1;
- assert(tree);
-
- #ifdef DEBUG_BTREE
- printf("\n 开始创建 B-树,关键字为:\n");
- for (i = 0; i < length; i++) {
- printf(" %c ", data[i]);
- }
- printf("\n");
- #endif
-
- for (i = 0; i < length; i++) {
- #ifdef DEBUG_BTREE
- printf("\n插入关键字 %c:\n", data[i]);
- #endif
-
- BTree_search(*tree,data[i],&pos);
- if (pos!=-1)
- {
- printf("this key %c is in the B-tree,not to insert.\n",data[i]);
- }else{
- BTree_insert(tree, data[i]);
- }
-
- #ifdef DEBUG_BTREE
- BTree_print(*tree,1);
- #endif
- }
-
- printf("\n");
- }
-
- void BTree_destroy(BTree* tree)
- {
- int i;
- BTNode* node = *tree;
-
- if (node) {
- for (i = 0; i <= node->keynum; i++) {
- BTree_destroy(&node->child[i]);
- }
-
- free(node);
- }
-
- *tree = NULL;
- }
测试文件:(测试B-Tree基本的操作接口)
-
-
-
-
-
-
-
-
-
- #include <stdio.h>
- #include "btree.h"
-
- void test_BTree_search(BTree tree, KeyType key)
- {
- int pos = -1;
- BTNode* node = BTree_search(tree, key, &pos);
- if (node) {
- printf("在%s节点(包含 %d 个关键字)中找到关键字 %c,其索引为 %d\n",
- node->isLeaf ? "叶子" : "非叶子",
- node->keynum, key, pos);
- }
- else {
- printf("在树中找不到关键字 %c\n", key);
- }
- }
-
- void test_BTree_remove(BTree* tree, KeyType key)
- {
- printf("\n移除关键字 %c \n", key);
- BTree_remove(tree, key);
- BTree_print(*tree);
- printf("\n");
- }
-
- void test_btree()
- {
-
- KeyType array[] = {
- 'G','G', 'M', 'P', 'X', 'A', 'C', 'D', 'E', 'J', 'K',
- 'N', 'O', 'R', 'S', 'T', 'U', 'V', 'Y', 'Z', 'F', 'X'
- };
- const int length = sizeof(array)/sizeof(KeyType);
- BTree tree = NULL;
- BTNode* node = NULL;
- int pos = -1;
- KeyType key1 = 'R';
- KeyType key2 = 'B';
-
-
- BTree_create(&tree, array, length);
-
- printf("\n=== 创建 B- 树 ===\n");
- BTree_print(tree);
- printf("\n");
-
-
- test_BTree_search(tree, key1);
- printf("\n");
- test_BTree_search(tree, key2);
-
-
- test_BTree_remove(&tree, key2);
- printf("\n");
-
-
- printf("\n插入关键字 %c \n", key2);
- BTree_insert(&tree, key2);
- BTree_print(tree);
- printf("\n");
-
- test_BTree_search(tree, key2);
-
-
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'M';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'E';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'G';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'A';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'D';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'K';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'P';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'J';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'C';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'X';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'O';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'V';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'R';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'U';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'T';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
- key2 = 'N';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
- key2 = 'S';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
- key2 = 'Y';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
- key2 = 'F';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
- key2 = 'Z';
- test_BTree_remove(&tree, key2);
- test_BTree_search(tree, key2);
-
-
- BTree_destroy(&tree);
- }
-
- int main()
- {
- test_btree();
-
- return 0;
- }
另外参考《Data.structures.and.Program.Design.in.Cpp》-Section 11.3:EXTERNALSEARCHING:B-TREES的讲解实现,这边书个人认为比较经典,如果对数据结构和算法比较感兴趣的话,可以作为参考读物,不错的,根据数据结构上的操作与程序上的实现相结合,讲的很细。这本书好像没有中文版的,即使有,也推荐看原版吧,毕竟写代码都是用英文字符,实现也比较贴切易懂。去网上找这本书的资料还挺多的。而且国内有些大学也参考这本书讲解数据结构和算法。比如:http://sist.sysu.edu.cn/~isslxm/DSA/CS09/。
头文件:(采用C++模板(template)来实现B-Tree基本的操作接口)
-
-
-
-
-
-
-
-
-
-
-
- #ifndef B_Tree_H_
- #define B_Tree_H_
-
- enum Error_code{overflow=-2,duplicate_error=-1,not_present=0,success=1};
-
- template <class Record, int order>
- struct B_node {
-
- int count;
- Record data[order - 1];
- B_node<Record, order> *branch[order];
-
- B_node();
- };
-
- template <class Record, int order>
- class B_tree {
- public:
-
-
- Error_code search_tree(Record &target);
-
- Error_code insert(const Record &new_entry);
-
- Error_code remove(const Record &target);
-
- protected:
-
-
-
-
-
- Error_code recursive_search_tree(B_node<Record, order> *current, Record &target);
-
- Error_code search_node(B_node<Record, order> *current, const Record &target, int &position);
-
-
-
- Error_code push_down(B_node<Record, order> *current,const Record &new_entry,
- Record &median,B_node<Record, order> *&right_branch);
-
- void push_in(B_node<Record, order> *current, const Record &entry,
- B_node<Record, order> *right_branch, int position);
-
- void split_node(B_node<Record, order> *current, const Record &extra_entry, B_node<Record, order> *extra_branch,
- int position, B_node<Record, order> *&right_half, Record &median);
-
-
-
- Error_code recursive_remove(B_node<Record, order> *current, const Record &target);
-
- void remove_data(B_node<Record, order> *current, int position);
-
- void copy_in_predecessor(B_node<Record, order> *current, int position);
-
- void restore(B_node<Record, order> *current,int position);
-
- void move_left(B_node<Record, order> *current, int position);
-
- void move_right(B_node<Record, order> *current,int position);
-
- void combine(B_node<Record, order> *current, int position);
-
- private:
-
- B_node<Record, order> *root;
-
-
- };
-
- #endif //end B_Tree_H_
原文件:(实现B-Tree基本的基本操作)
-
-
-
-
-
-
-
-
-
-
- #include "B_Tree.h"
-
- template <class Record, int order>
- Error_code B_tree<Record, order>::search_tree(Record &target)
-
-
-
-
-
-
-
- {
- return recursive_search_tree(root, target);
- }
-
-
- template <class Record, int order>
- Error_code B_tree<Record, order>::recursive_search_tree(
- B_node<Record, order> *current, Record &target)
-
-
-
-
-
-
-
- {
- Error_code result = not_present;
- int position;
- 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 Record, int order>
- Error_code B_tree<Record, order>::search_node(
- B_node<Record, order> *current, const Record &target, int &position)
-
-
-
-
-
-
-
-
-
- {
- position = 0;
- while (position < current->count && target > current->data[position])
- position++;
- if (position < current->count && target == current->data[position])
- return success;
- else
- return not_present;
- }
-
-
- template <class Record, int order>
- Error_code B_tree<Record, order>::insert(const Record &new_entry)
-
-
-
-
-
-
-
-
- {
- Record median;
- B_node<Record, order> *right_branch, *new_root;
- Error_code result = push_down(root, new_entry, median, right_branch);
-
- if (result == overflow) {
-
- new_root = new B_node<Record, 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 Record, int order>
- Error_code B_tree<Record, order>::push_down(
- B_node<Record, order> *current,
- const Record &new_entry,
- Record &median,
- B_node<Record, 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)
- result = duplicate_error;
- else {
- Record extra_entry;
- B_node<Record, order> *extra_branch;
- result = push_down(current->branch[position], new_entry,
- extra_entry, extra_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 Record, int order>
- void B_tree<Record, order>::push_in(B_node<Record, order> *current,
- const Record &entry, B_node<Record, order> *right_branch, int position)
-
-
-
-
-
-
- {
- 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 Record, int order>
- void B_tree<Record, order>::split_node(
- B_node<Record, order> *current,
- const Record &extra_entry,
- B_node<Record, order> *extra_branch,
- int position,
- B_node<Record, order> *&right_half,
- Record &median)
-
-
-
-
-
-
-
-
-
-
- {
- right_half = new B_node<Record, 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 + 1 - mid] = current->branch[i + 1];
- }
- current->count = mid;
- right_half->count = order - 1 - mid;
- push_in(current, extra_entry, extra_branch, position);
- }
- else {
- mid++;
- for (int i = mid; i < order - 1; i++) {
- right_half->data[i - mid] = current->data[i];
- right_half->branch[i + 1 - mid] = current->branch[i + 1];
- }
- current->count = mid;
- right_half->count = order - 1 - mid;
- push_in(right_half, extra_entry, extra_branch, position - mid);
- }
- median = current->data[current->count - 1];
- right_half->branch[0] = current->branch[current->count];
- current->count--;
- }
-
-
- template <class Record, int order>
- Error_code B_tree<Record, order>::remove(const Record &target)
-
-
-
-
-
-
-
- {
- Error_code result;
- result = recursive_remove(root, target);
- if (root != NULL && root->count == 0) {
- B_node<Record, order> *old_root = root;
- root = root->branch[0];
- delete old_root;
- }
- return result;
- }
-
-
- template <class Record, int order>
- Error_code B_tree<Record, order>::recursive_remove(
- B_node<Record, order> *current, const Record &target)
-
-
-
-
-
-
-
-
-
-
- {
- Error_code result;
- int position;
- if (current == NULL) result = 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 Record, int order>
- void B_tree<Record, order>::remove_data(B_node<Record, order> *current,
- int position)
-
-
-
-
- {
- for (int i = position; i < current->count - 1; i++)
- current->data[i] = current->data[i + 1];
- current->count--;
- }
-
-
- template <class Record, int order>
- void B_tree<Record, order>::copy_in_predecessor(
- B_node<Record, order> *current, int position)
-
-
-
-
- {
- B_node<Record, order> *leaf = current->branch[position];
- while (leaf->branch[leaf->count] != NULL)
- leaf = leaf->branch[leaf->count];
- current->data[position] = leaf->data[leaf->count - 1];
- }
-
-
- template <class Record, int order>
- void B_tree<Record, order>::restore(B_node<Record, order> *current,
- int position)
-
-
-
-
-
-
-
- {
- 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 Record, int order>
- void B_tree<Record, order>::move_left(B_node<Record, order> *current,
- int position)
-
-
-
-
-
-
-
- {
- B_node<Record, order> *left_branch = current->branch[position - 1],
- *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 Record, int order>
- void B_tree<Record, order>::move_right(B_node<Record, order> *current,
- int position)
-
-
-
-
-
-
-
- {
- B_node<Record, order> *right_branch = current->branch[position + 1],
- *left_branch = current->branch[position];
- 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 Record, int order>
- void B_tree<Record, order>::combine(B_node<Record, order> *current,
- int position)
-
-
-
-
-
-
-
- {
- int i;
- B_node<Record, order> *left_branch = current->branch[position - 1],
- *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 (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 (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;
- }
测试文件:(待写)
//原文地址