数据结构进阶——B+树

B+树是一种树数据结构,是B树的一种变体,也属于平衡多路查找树。它具有以下特点:

  1. 包含根节点、内部节点和叶子节点。根节点可能是叶子节点,也可能是包含两个或两个以上子节点的节点。内部节点如果拥有k个关键字则有k+1个子节点。非叶子节点不保存数据,只保存关键字用作索引,所有数据都保存在叶子节点中。

  2. B+树非叶子节点不保存关键字记录的指针,只进行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增加。

  3. B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样。

  4. B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针。

  5. B+树全节点遍历更快:B+树遍历整棵树只需要遍历所有的叶子节点即可,,而不需要像B树一样需要对每一层进行遍历,这有利于数据库做全表扫描。

  6. 由于B+树的这些特点,它在数据库和操作系统的文件系统中被广泛应用。在数据库中,B+树索引是最常见也是数据库中使用最为频繁的一种索引。在文件系统中,B+树被用于构建文件系统的元数据索引。此外,NTFS、ReiserFS、NSS、XFS、JFS、ReFS和BFS等文件系统都在使用B+树作为元数据索引。

以下是一个简单的B+树实现,包括插入和查找操作

#include   
#include   
  
#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+树实现,还需要进一步完善代码。

你可能感兴趣的:(b树)