首页 > 其他分享 >【408考点之数据结构】B树和B+树

【408考点之数据结构】B树和B+树

时间:2024-07-03 09:59:45浏览次数:20  
标签:node BTreeNode leaf int keys 考点 数据结构 节点 408

B树和B+树

在大规模数据存储和检索中,B树和B+树是两种广泛使用的数据结构。它们被设计用来高效地管理数据,使得插入、删除和查找操作都能在对数时间内完成。以下是对这两种数据结构的详细介绍。

1. B树(B-Tree)

定义:B树是一种自平衡的多路查找树,通常用于数据库和文件系统中。B树的所有叶子节点位于同一层,且内部节点可以包含多个关键字和子树指针。

性质

  • 每个节点包含关键字的数量范围为 ( [t-1, 2t-1] ),其中 ( t ) 是B树的阶数。
  • 除根节点外,每个内部节点至少有 ( t ) 个子节点。
  • 所有叶子节点位于同一层。
  • 插入和删除操作需要维护树的平衡。

实现

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

// B树节点结构
typedef struct BTreeNode {
    int *keys;  // 关键字数组
    int t;      // 最小度数
    struct BTreeNode **C; // 子树指针数组
    int n;      // 当前关键字数量
    int leaf;   // 叶子节点标志
} BTreeNode;

// 创建新的B树节点
BTreeNode* createNode(int t, int leaf) {
    BTreeNode* node = (BTreeNode*)malloc(sizeof(BTreeNode));
    node->t = t;
    node->leaf = leaf;
    node->keys = (int*)malloc(sizeof(int) * (2 * t - 1));
    node->C = (BTreeNode**)malloc(sizeof(BTreeNode*) * (2 * t));
    node->n = 0;
    return node;
}

// B树插入操作略
// 示例代码略
2. B+树(B+ Tree)

定义:B+树是B树的变种,具有所有叶子节点按顺序链接的特性,使得范围查找更加高效。所有数据都存储在叶子节点中,内部节点只存储索引。

性质

  • 内部节点只存储索引,不存储实际数据。
  • 所有数据都存储在叶子节点中,并通过链表链接。
  • 插入和删除操作会影响到索引节点,但数据节点的顺序保持不变。

实现

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

// B+树节点结构
typedef struct BPlusTreeNode {
    int *keys;  // 关键字数组
    int t;      // 最小度数
    struct BPlusTreeNode **C; // 子树指针数组
    struct BPlusTreeNode *next; // 下一个叶子节点指针
    int n;      // 当前关键字数量
    int leaf;   // 叶子节点标志
} BPlusTreeNode;

// 创建新的B+树节点
BPlusTreeNode* createBPlusNode(int t, int leaf) {
    BPlusTreeNode* node = (BPlusTreeNode*)malloc(sizeof(BPlusTreeNode));
    node->t = t;
    node->leaf = leaf;
    node->keys = (int*)malloc(sizeof(int) * (2 * t - 1));
    node->C = (BPlusTreeNode**)malloc(sizeof(BPlusTreeNode*) * (2 * t));
    node->next = NULL;
    node->n = 0;
    return node;
}

// B+树插入操作略
// 示例代码略

B树和 B+树的比较

  • 结构差异
    • B树:内部节点和叶子节点都存储数据。
    • B+树:内部节点只存储索引,所有数据都在叶子节点中,且叶子节点通过链表连接。
  • 查找效率
    • B树:查找路径较短,但每个节点的访问次数较多。
    • B+树:查找路径较长,但叶子节点间的顺序访问更高效,适合范围查找。
  • 插入和删除
    • B树:插入和删除可能涉及到内部节点和叶子节点的调整。
    • B+树:插入和删除主要影响叶子节点,内部节点只需调整索引,且顺序访问更友好。

应用场景

  • 数据库索引:B树和B+树广泛应用于数据库索引结构中,提供高效的数据存储和查找方式。
  • 文件系统:文件系统中使用B树和B+树管理文件目录和索引,提高文件检索效率。
  • 内存管理:操作系统中的内存管理也可以利用B树和B+树进行页表管理和快速查找。

示例代码

以下是一个简单的B树插入操作的示例代码:

// B树插入操作示例代码
#include <stdio.h>
#include <stdlib.h>

typedef struct BTreeNode {
    int *keys; 
    int t; 
    struct BTreeNode **C; 
    int n; 
    int leaf; 
} BTreeNode;

BTreeNode* createNode(int t, int leaf) {
    BTreeNode* node = (BTreeNode*)malloc(sizeof(BTreeNode));
    node->t = t;
    node->leaf = leaf;
    node->keys = (int*)malloc(sizeof(int) * (2 * t - 1));
    node->C = (BTreeNode**)malloc(sizeof(BTreeNode*) * (2 * t));
    node->n = 0;
    return node;
}

void insertNonFull(BTreeNode* node, int k) {
    int i = node->n - 1;

    if (node->leaf) {
        while (i >= 0 && node->keys[i] > k) {
            node->keys[i + 1] = node->keys[i];
            i--;
        }
        node->keys[i + 1] = k;
        node->n += 1;
    } else {
        while (i >= 0 && node->keys[i] > k)
            i--;

        if (node->C[i + 1]->n == 2 * node->t - 1) {
            splitChild(node, i + 1, node->C[i + 1]);

            if (node->keys[i + 1] < k)
                i++;
        }
        insertNonFull(node->C[i + 1], k);
    }
}

void splitChild(BTreeNode* parent, int i, BTreeNode* y) {
    int t = y->t;
    BTreeNode* z = createNode(t, y->leaf);
    z->n = t - 1;

    for (int j = 0; j < t - 1; j++)
        z->keys[j] = y->keys[j + t];

    if (!y->leaf) {
        for (int j = 0; j < t; j++)
            z->C[j] = y->C[j + t];
    }

    y->n = t - 1;

    for (int j = parent->n; j >= i + 1; j--)
        parent->C[j + 1] = parent->C[j];

    parent->C[i + 1] = z;

    for (int j = parent->n - 1; j >= i; j--)
        parent->keys[j + 1] = parent->keys[j];

    parent->keys[i] = y->keys[t - 1];
    parent->n += 1;
}

void traverse(BTreeNode* root) {
    int i;
    for (i = 0; i < root->n; i++) {
        if (!root->leaf)
            traverse(root->C[i]);
        printf(" %d", root->keys[i]);
    }
    if (!root->leaf)
        traverse(root->C[i]);
}

int main() {
    int t = 3;
    BTreeNode* root = createNode(t, 1);
    insertNonFull(root, 10);
    insertNonFull(root, 20);
    insertNonFull(root, 5);
    insertNonFull(root, 6);
    insertNonFull(root, 12);
    insertNonFull(root, 30);
    insertNonFull(root, 7);
    insertNonFull(root, 17);

    printf("Traversal of the constructed tree is ");
    traverse(root);
    printf("\n");

    return 0;
}

这个示例展示了如何在B树中插入元素,并通过遍历操作显示树中的关键字。通过这种方式,可以高效地进行数据管理和查找操作。

标签:node,BTreeNode,leaf,int,keys,考点,数据结构,节点,408
From: https://blog.csdn.net/gygkhd/article/details/140144378

相关文章

  • 【408计算机组成原理】计算机的性能指标
    计算机的性能指标计算机性能指标是评估计算机系统运行效率和处理能力的重要标准。常见的性能指标包括处理速度、存储器性能、输入/输出性能、系统吞吐量、多任务处理能力和能效比。以下是详细介绍:1.处理速度时钟频率:指CPU每秒执行的指令周期数,单位为赫兹(Hz)。时钟频率越......
  • [JLU] 数据结构与算法上机题解思路分享-第三次上机
    前言首先,请务必自己尽全力尝试实现题目,直接看成品代码,思维就被拘束了,也很容易被查重。这里只是思路解析的博客,代码仓库在JLU_Data_Structures_Record希望你能在这里找到你想要的:)正文A图的创建分数10作者朱允刚单位吉林大学请编写程序创建一个有向图。有向图中包含......
  • SpringBoot的重要考点--自动配置
    SpringBoot的自动配置是其核心特性之一,它允许开发者快速启动和运行Spring应用,而无需编写大量的样板代码。SpringBoot的自动配置主要通过以下几个方式实现:@EnableAutoConfiguration:这个注解是SpringBoot自动配置的入口,它告诉SpringBoot根据类路径中的jar包和配置文件来......
  • 数据结构小学期第2天
    今日完成了小组分发的剩下两个题目其一,老板的作息表新浪微博上有人发了某老板的作息时间表,表示其每天4:30就起床了。但立刻有眼尖的网友问:这时间表不完整啊,早上九点到下午一点干啥了?本题就请你编写程序,检查任意一张时间表,找出其中没写出来的时间段。输入格式:输入第一行给出......
  • PART1-Oracle关系数据结构
    2.Oracle关系数据结构2.1.表和表簇2.1.1.模式对象简介数据库模式是数据结构的逻辑容器,这些数据结构称为模式对象。模式对象的例子有表和索引。模式对象是通过SQL创建和操作的。一个数据库用户拥有密码和各种数据库权限。每个用户拥有一个与其同名的模式。模式包含了属于......
  • [JLU] 数据结构与算法上机题解思路分享-第二次上机
    前言首先,请务必自己尽全力尝试实现题目,直接看成品代码,思维就被拘束了,也很容易被查重。这里只是思路解析的博客,代码仓库在JLU_Data_Structures_Record希望你能在这里找到你想要的:)正文A二叉树的创建与遍历分数10作者朱允刚单位吉林大学通过带空指针信息的先根序列(......
  • 数据结构:期末考 第六次测试(总复习)
    一、单选题(共50题,100分)1、表长为n的顺序存储的线性表,当在任何位置上插入或删除一个元素的概率相等时,插入一个元素所需移动元素的平均个数为(D).(2.0)A、(n−1)/2B、nC、n+1D、n/22、设栈S和队列Q的初始状态为空,元素e1、e2、e3、e4、e5和e6依次通过栈S,一个元素出栈后......
  • 【数据结构】常见的几种数据结构
    常见的数据结构:数组、链表、队列、栈、、堆、二叉树、B树、哈希表、图数组因为数组内的元素是连续存储的,所以数组中元素的地址,可以通过其索引计算出来。根据索引查找元素,时间复杂度是\(O(1)\)。动态数组动态数组具体代码实现importjava.util.Arrays;importjava.util.Ite......
  • 数据结构 —— Trie 树
    一个笔记需要一张头图:Trie树是一种维护(广义)字符串(我们认为广义字符串是一切可以被线性描述的类型,例如,我们认为整数(无论是哪种进制下)是一种广义字符串;有理数也是一种广义字符串(使用无限循环小数方式表述,可能需要一些特殊处理。))的数据结构,其特征为适于处理前缀类型或寻找类型(i.e.......
  • 探索数据结构:队列的的实现与应用
     ......