B树的构建C语言实现
B树是文件系统的基石,也是数据库的基石。学会B树才能更好的学习B+树。
#include <stdio.h> #include <stdlib.h> typedef struct Node { int level; // 树的阶 int keyNum; // 关键字数量 int* keys; // 关键字数组 int childNum; // 孩子数量 struct Node** children; // 孩子数组 struct Node* parent; // 父亲指针 } Node; Node* initNode(int level) { Node* node = (Node*) malloc(sizeof(Node)); node->level = level; node->keyNum = 0; node->childNum = 0; // (null) (level - 1) (放新添加的位) == level + 1 node->keys = (int*) calloc(level + 1, sizeof(int)); node->children = (Node**) calloc(level, sizeof(Node*)); node->parent = NULL; int i = 0; for (; i< level; i++) { node->children[i] = NULL; node->keys[i] = 0; } node->keys[i] = 0; return node; } /** * 在结点处找到合适的插入索引 * @param node * @param data * @return */ int findSuitIndex(Node* node, int data) { int index = 1; for (; index <= node->keyNum; ++index) { if (data < node->keys[index]) { break; } } // 循环跳出时, index会再加一次, 所以会是第一次大于data的索引 return index; } /** * 找到合适插入的叶子结点 * @param T * @param data * @return */ Node* findSuitLeafNode(Node* T, int data) { if (T->childNum == 0) { return T; } int index = findSuitIndex(T, data); return findSuitLeafNode(T->children[index - 1], data); } void addData(Node* node, int data, Node** T) { int index = findSuitIndex(node, data); for (int i = node->keyNum; index <= i; i--) { node->keys[i + 1] = node->keys[i]; } node->keys[index] = data; node->keyNum++; // 判断是否需要分裂 if (node->keyNum == node->level) { // mid = ceil(node->level), 向上取整 int mid = node->level / 2 + (node->level & 1); Node* lChild = initNode(node->level); Node* rChild = initNode(node->level); // 将值赋给子结点 for (int i = 1; i < mid; i++) { addData(lChild, node->keys[i], T); } for (int i = mid + 1; i < node->level + 1; i++) { addData(rChild, node->keys[i], T); } for (int i = 0; i < mid; i++) { lChild->children[i] = node->children[i]; if (lChild->children[i] != NULL) { lChild->children[i]->parent = lChild; lChild->childNum++; } } int rIndex = 0; for (int i = mid; i < node->childNum; i++) { rChild->children[rIndex++] = node->children[i]; if (rChild->children[i] != NULL) { rChild->children[i]->parent = rChild; rChild->childNum++; } } // 处理父结点 if (node->parent == NULL) { Node* newParent = initNode(node->level); newParent->children[0] = lChild; newParent->children[1] = rChild; newParent->childNum = 2; lChild->parent = newParent; rChild->parent = newParent; addData(newParent, node->keys[mid], T); *T = newParent; free(node); } else { int pIndex = findSuitIndex(node->parent, node->keys[mid]); node->parent->children[pIndex - 1] = lChild; if (node->parent->children[pIndex] != NULL) { for (int i = node->parent->childNum - 1; i >= pIndex; i--) { node->parent->children[i + 1] = node->parent->children[i]; } } node->parent->children[pIndex] = rChild; node->parent->childNum++; lChild->parent = node->parent; rChild->parent = node->parent; addData(node->parent, node->keys[mid], T); free(node); } } } void insert(Node** T, int data) { Node* node = findSuitLeafNode(*T, data); addData(node, data, T); } void printTree(Node* T) { if (T != NULL) { for (int i = 1; i <= T->keyNum; i++) { printf("%d, ", T->keys[i]); } printf("\n"); for (int i = 0; i < T->childNum; i++) { printTree(T->children[i]); } } } int main() { printf("Hello, BTree!\n"); Node* T = initNode(5); for (int i = 1; i <= 15; i++) { insert(&T, i); } printTree(T); return 0; }
本文作者:jikefan
本文链接:https://www.cnblogs.com/jikefan/articles/18174969
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。