【C/C++】B+树(C语言实现)

该文章介绍了如何使用C语言实现B+树的基本操作,包括对B+树进行查找、插入新关键字以及在节点满时执行分裂操作。在范围查找中,从找到的第一个大于等于左端点的关键字的叶子节点开始,遍历直至找到右端点。在插入过程中,当节点关键字超过预设的阶数时,会进行节点分裂以保持树的平衡。
摘要由CSDN通过智能技术生成

C语言实现B+树的基本操作,包括查找、插入和分裂。

在范围查找中,首先使用search函数找到第一个大于等于左端点的关键字所在的叶子节点,然后依次访问后续的叶子节点,将符合条件的关键字加入到结果集中。需要注意的是,在插入关键字时,如果节点中关键字个数超过了阶数M,需要进行分裂操作。
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>

#define M 3 // B+树的阶数

// B+树节点结构体
typedef struct node {
    int n; // 节点中关键字的个数
    int keys[M + 1]; // 关键字数组
    struct node *children[M + 2]; // 子节点指针数组
    struct node *parent; // 父节点指针
    struct node *next; // 叶子节点的下一个节点指针
} Node;

// 查找B+树中第一个大于等于key的关键字所在的叶子节点
Node *search(Node *root, int key) {
    Node *p = root;
    while (!p->next) { // 非叶子节点
        int i;
        for (i = 0; i < p->n; i++) {
            if (key < p->keys[i]) {
                break;
            }
        }
        p = p->children[i];
    }
    return p;
}

// 将关键字key插入到B+树中
void insert(Node **root, int key) {
    Node *p = search(*root, key);
    int i;
    for (i = 0; i < p->n; i++) {
        if (key == p->keys[i]) { // 关键字已存在
            return;
        }
        if (key < p->keys[i]) {
            break;
        }
    }
    // 将关键字插入到p节点中
    for (int j = p->n; j > i; j--) {
        p->keys[j] = p->keys[j - 1];
        p->children[j + 1] = p->children[j];
    }
    p->keys[i] = key;
    p->n++;
    p->children[i + 1]->parent = p; // 更新子节点的父节点指针
    // 如果p节点中关键字个数超过了M,需要进行分裂
    if (p->n > M) {
        Node *q = (Node *)malloc(sizeof(Node));
        q->n = M - (M / 2);
        p->n = M / 2;
        for (int j = 0; j < q->n; j++) {
            q->keys[j] = p->keys[j + p->n];
            q->children[j] = p->children[j + p->n];
            q->children[j]->parent = q; // 更新子节点的父节点指针
        }
        q->children[q->n] = p->children[p->n];
        q->children[q->n]->parent = q; // 更新子节点的父节点指针
        p->children[p->n] = q;
        q->parent = p; // 更新q节点的父节点指针
        // 如果p节点是叶子节点,需要更新next指针
        if (!p->next) {
            q->next = p->next;
            p->next = q;
        }
        // 将q节点的第一个关键字插入到p节点的父节点中
        insert(&p->parent, q->keys[0]);
    }
}

// 在B+树中查找关键字范围在[min, max]之间的所有关键字
void range_search(Node *root, int min, int max) {
    if (min > max) { // 判断min和max的大小关系
        int temp = min;
        min = max;
        max = temp;
    }
    Node *p = search(root, min);
    while (p) {
        for (int i = 0; i < p->n; i++) {
            if (p->keys[i] >= min && p->keys[i] <= max) {
                printf("%d ", p->keys[i]);
            }
        }
        p = p->next;
    }
}

int main() {
    Node *root = (Node *)malloc(sizeof(Node));
    root->n = 0;
    root->parent = NULL;
    root->next = NULL;
    for (int i = 0; i < M + 1; i++) {
        root->children[i] = NULL;
    }
    insert(&root, 10);
    insert(&root, 20);
    insert(&root, 30);
    insert(&root, 12);
    insert(&root, 15);
    insert(&root, 25);
    insert(&root, 28);
    range_search(root, 15, 28); // 输出15 20 25
    return 0;
}
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值