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

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树中插入元素,并通过遍历操作显示树中的关键字。通过这种方式,可以高效地进行数据管理和查找操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/769334.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

UE5 02-给物体一个扭矩力

需要注意的是: 1.弹簧臂 可以使用绝对旋转 这样就可以不跟随父物体Player的旋转 2.弹簧臂 进行碰撞测试勾选,当这个弹簧线被遮挡,摄像机会切换到碰撞点位置 进行碰撞测试勾选,当这个弹簧线被遮挡,摄像机不会切换到碰撞点位置

yolov8 目标检测快速streamlit可视化界面

参考&#xff1a; https://github.com/ultralytics/ultralytics/blob/2330caa50a8a8e0bb61408df8dca0721fb350dbe/ultralytics/solutions/streamlit_inference.py 版本&#xff1a; ultralytics 8.2.27 # Ultralytics YOLO &#x1f680;, AGPL-3.0 licen…

买卖股票的最佳时期含冷冻期(leetcode)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 也就有这样的状态转移方程&#xff1a; 买入&#xff1a;dp[i][0] max(dp[i-1][1] - prices[i], dp[i-1][0]); 可买入&#xff1a;dp[i][1] max(dp[i-1][1], dp[i-1][2]); 冷冻期&#xff1a;dp[i][2] dp[i-1][0] prices…

mybatis、mybatis-plus插件开发,实现数据脱敏功能

首先说一下mybatis中四大组件的作用&#xff0c;下面开发的插件拦截器会使用 四大组件Executor、StatementHandler、ParameterHandler、ResultSetHandler Executor&#xff1a; Executor 是 MyBatis 中的执行器&#xff0c;负责 SQL 语句的执行工作。它通过调度 StatementHan…

在SpringBoot 3.0环境下创建一个SpringBoot 项目

一、环境配置 1.专业版的IDEA 版本号&#xff1a;尽量选择不要太老&#xff0c;不要太早 这里以2023.3.1为例。 官网&#xff1a;Download IntelliJ IDEA – The Leading Java and Kotlin IDE (jetbrains.com) 破解版&#xff1a;网上找资料哦&#xff01;&#xff01;&#…

【Python】基于动态规划和K聚类的彩色图片压缩算法

引言 当想要压缩一张彩色图像时&#xff0c;彩色图像通常由数百万个颜色值组成&#xff0c;每个颜色值都由红、绿、蓝三个分量组成。因此&#xff0c;如果我们直接对图像的每个像素进行编码&#xff0c;会导致非常大的数据量。为了减少数据量&#xff0c;我们可以尝试减少颜色…

7.7、指针和函数

代码 #include <iostream> using namespace std;//实现两个数字进行交换 void swap01(int a, int b) {int temp a;a b;b temp;cout << "swap01a " << a << endl;cout << "swap01b " << b << endl; }void sw…

AUTOSAR NvM模块(七)

NvM工具配置demo 一切block的配置根据自己的需求&#xff01; NvMBlockDescriptor NvM Common MemIf General FeeBlockConfiguration FeeGeneral

Go语言学习:每日一练3

Go语言学习&#xff1a;每日一练3 目录 Go语言学习&#xff1a;每日一练3方法接口继承类型断言 方法 方法是一类有接收者参数的函数。 接收者的类型定义和方法的声明必须在一个包里 type MyInt intfunc (m MyInt) Add(add int) int {return int(m) add } //OR func (m *MyInt)…

苹果Mac电脑能玩什么游戏 Mac怎么运行Windows游戏

相对于Windows平台来说&#xff0c;Mac电脑可玩的游戏较少。虽然苹果设备的性能足以支持各种大型游戏&#xff0c;但由于系统以及苹果配套服务的限制&#xff0c;很多游戏无法在Mac系统中运行。不过&#xff0c;借助虚拟机软件&#xff0c;Mac电脑可以突破系统限制玩更多的游戏…

66.Python-web框架-Django-免费模板django-datta-able的分页的一种方式

目录 1.方案介绍 1.1实现效果 1.2django.core.paginator Paginator 类: Page 类: EmptyPage 和 PageNotAnInteger 异常: 1.3 templatetags 2.方案步骤 2.1创建一个common app 2.2创建plugins/_pagination.html 2.3 其他app的views.py查询方法 2.4在AIRecords.html里…

Unity中模拟抛物线(非Unity物理)

Unity中模拟抛物线非Unity物理 介绍剖析问题以及所需公式重力加速度公式&#xff1a;h 1/2*g*t*t(h 1/2 * g * t ^ 2)速度公式&#xff1a;Vt V初 a * t 主要代码总结 介绍 用Unity物理系统去做的抛物线想要控制速度或者想要细微的控制一些情况是非常困难的。所以想要脱离U…

Flutter——最详细(Drawer)使用教程

背景 应用左侧或右侧导航面板&#xff1b; 属性作用elevation相当于阴影的大小 import package:flutter/material.dart;class CustomDrawer extends StatelessWidget {const CustomDrawer({Key? key}) : super(key: key);overrideWidget build(BuildContext context) {return…

【Python】已解决ModuleNotFoundError: No module named ‘tensorflow‘

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决ModuleNotFoundError: No module named ‘tensorflow‘ 一、分析问题背景 ModuleNotFoundError: No module named ‘tensorflow’ 是一个常见的错误&#xff0c;通常在Pytho…

MATLAB常用语句总结7

MATLAB总结7&#xff1a;常见错误归纳 文章目录 MATLAB总结7&#xff1a;常见错误归纳前言一、rand 的使用二、蒙塔卡罗求解方法1.函数的定义2.函数引用 三、函数引用与多变量四、矩阵引用五、非线性函数&#xff1a;fmincon的使用六、线性规划函数1.linprog2.fminbnd、fminsea…

Docker学习笔记(二)镜像、容器、仓库相关命令操作

一、docker镜像操作 列出镜像列表 我们可以使用 docker images 来列出本地主机上的镜像。 各个选项说明: REPOSITORY&#xff1a;表示镜像的仓库源 TAG&#xff1a;镜像的标签 IMAGE ID&#xff1a;镜像ID CREATED&#xff1a;镜像创建时间 SIZE&#xff1a;镜像大小 查…

pdf太大怎么压缩大小,pdf文件太大如何压缩变小

在数字化时代&#xff0c;pdf文件已成为我们工作、学习和生活中不可或缺的一部分。然而&#xff0c;随着文件内容的丰富&#xff0c;pdf文件的体积也日益增大&#xff0c;给存储和传输带来不便。本文将为你详细介绍四种实用的pdf文件压缩方法&#xff0c;帮助你轻松减小pdf容量…

【ROS2】初级:CLI工具 -配置环境

目标&#xff1a;本教程将指导您如何准备您的 ROS 2 环境。 教程级别&#xff1a;初学者 时间&#xff1a;5 分钟 目录 背景 先决条件 任务 源代码设置文件将源添加到您的 shell 启动脚本检查环境变量 摘要 下一步 背景 ROS 2 依赖于使用 shell 环境组合工作空间的概念。“Work…

C# Winform自制多轴力臂(简单易懂,方便扩展)

WinForms框架广泛应用于上位机开发领域&#xff0c;其中对力臂的精准控制是常见需求之一。本文深入探讨了如何创建自定义的多轴力臂图形控件&#xff0c;不仅涵盖了力臂图形控件的角度调节机制&#xff0c;还详细展示了如何实现力臂运动的生动动态效果&#xff0c;为开发者提供…

解决VSCode中导入PyTorch时报错的HTTP错误与Channel冲突

问题描述与解释 在Anaconda中成功安装PyTorch&#xff0c;并进行了验证&#xff1a; (base) C:\Users\Hui>conda activate pytorch(pytorch) C:\Users\\Hui>python Python 3.8.19 (default, Mar 20 2024, 19:55:45) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on …