B+树是一种树数据结构,是B树的一种变体,也属于平衡多路查找树。它具有以下特点:
-
包含根节点、内部节点和叶子节点。根节点可能是叶子节点,也可能是包含两个或两个以上子节点的节点。内部节点如果拥有k个关键字则有k+1个子节点。非叶子节点不保存数据,只保存关键字用作索引,所有数据都保存在叶子节点中。
-
B+树非叶子节点不保存关键字记录的指针,只进行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增加。
-
B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样。
-
B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针。
-
B+树全节点遍历更快:B+树遍历整棵树只需要遍历所有的叶子节点即可,,而不需要像B树一样需要对每一层进行遍历,这有利于数据库做全表扫描。
-
由于B+树的这些特点,它在数据库和操作系统的文件系统中被广泛应用。在数据库中,B+树索引是最常见也是数据库中使用最为频繁的一种索引。在文件系统中,B+树被用于构建文件系统的元数据索引。此外,NTFS、ReiserFS、NSS、XFS、JFS、ReFS和BFS等文件系统都在使用B+树作为元数据索引。
以下是一个简单的B+树实现,包括插入和查找操作
#include <stdio.h>
#include <stdlib.h>
#define MAX_KEYS_PER_NODE 3
#define MIN_KEYS_PER_NODE 2
typedef struct Node {
int keys[MAX_KEYS_PER_NODE + 1];
struct Node *children[MAX_KEYS_PER_NODE + 1];
int degree;
int isLeaf;
} Node;
Node* createNode(int degree) {
Node *newNode = (Node*)malloc(sizeof(Node));
newNode->degree = degree;
newNode->isLeaf = 0;
for (int i = 0; i <= degree; i++) {
newNode->children[i] = NULL;
}
return newNode;
}
void insertKey(Node *root, int key) {
if (root->isLeaf) {
if (root->degree < MAX_KEYS_PER_NODE) {
root->keys[root->degree] = key;
root->degree++;
} else {
printf("Leaf node is full, can't insert %d\n", key);
}
} else {
int i = 0;
while (i <= root->degree && root->keys[i] < key) i++;
if (root->children[i] == NULL) {
root->children[i] = createNode(root->degree + 1);
root->children[i]->isLeaf = 1;
}
insertKey(root->children[i], key);
}
}
int searchKey(Node *root, int key) {
if (root->isLeaf) {
for (int i = 0; i <= root->degree; i++) {
if (root->keys[i] == key) return i;
}
return -1; // Key not found in leaf node.
} else {
int i = 0;
while (i <= root->degree && root->keys[i] < key) i++;
if (root->children[i] != NULL) {
int index = searchKey(root->children[i], key);
if (index != -1) return index + root->degree + 1; // Adjust for parent node.
}
return -1; // Key not found in internal node.
}
}
以上代码实现了一个简单的B+树,包括插入和查找操作。插入操作会将键插入到合适的位置,并可能分裂节点。查找操作会沿着树向下查找,直到找到相应的键或到达叶子节点。如果键不存在,则返回-1。注意,这里的B+树实现非常简单,没有处理删除操作、合并节点等复杂情况。如果需要完整的B+树实现,还需要进一步完善代码。