当前位置: 首页 > article >正文

B树详解及其C语言实现

目录

一、B树的基本原理

二、B树操作过程图形化演示

三、B树的应用场景

四、C语言实现B树及示例

 五、代码执行结果说明

六、应用实例:文件系统目录索引

七、总结


一、B树的基本原理

B树(B-Tree) 是一种自平衡的树数据结构,专为高效处理磁盘或数据库中的大量数据而设计。它的核心特性是每个节点可以包含多个键和子节点指针,通过控制每个节点的最小/最大键数量,确保树的高度始终为对数级别。

B树的定义(以m阶B树为例)

     B树是一种多路搜索树,也被称为平衡多路查找树。与二叉搜索树不同,B树的每个节点可以拥有多个子节点和键值。B树的每个节点包含键值集合、子节点指针集合和一个平衡因子。键值集合按照从小到大的顺序排列,子节点指针集合按照左子节点、右子节点的顺序排列。平衡因子用于衡量节点的平衡性。

  1. 节点容量:B树的阶(Order)或分支因子(Branch Factor)通常用字母m表示,它定义了节点可以拥有的最大子节点数(即m个子节点)。因此,一个节点最多可以有m-1个键值。最少包含 m/2−1 个键(根节点除外)
  2. 子节点数:每个非叶子节点最多有 m个子节点,最少有 m/2个子节点
  3. 有序性:所有键在节点内按升序排列

  4. 平衡性

    • B树通过保持树的平衡性,确保所有叶子节点都在同一层,从而实现了高效的查找、插入和删除操作。
    • 这种平衡性确保了所有查找、插入和删除操作的时间复杂度都是O(log n),其中n是树中元素的数量。
  5. 操作原理

    • 查找操作:从根节点开始,通过比较要查找的键与节点中的键,决定是继续在左子树还是右子树中搜索,直到找到目标键或到达叶子节点为止。
    • 插入操作:找到合适的叶子节点,然后将新键插入该节点。如果插入后节点中的键的数量超过了m-1,则节点会分裂成两个节点,并将中间的键提升到父节点。如果父节点也满了,则继续向上分裂,直到根节点。如果根节点也分裂,则创建一个新的根节点,并包含分裂出的中间键。
    • 删除操作:找到包含要删除键的节点,并从节点中移除该键。如果删除后节点中的键的数量少于要求的最小数量(⌈m/2⌉-1),则需要重新分配或合并节点。重新分配通常是从兄弟节点借键,合并则是将当前节点与兄弟节点合并,并可能将父节点中的键下移。

二、B树操作过程图形化演示

示例:构建一个3阶B树(每个节点最多2个键,3个子节点)

插入序列:[10, 20, 5, 6, 12, 30, 7, 17]

1. 插入10(根节点):
[10]2. 插入20(直接填充根节点):
[10, 20]3. 插入5(根节点已满,触发分裂):[10]/   \[5]   [20]4. 插入6(插入到左子节点):[10]/   \[5,6] [20]5. 插入12(插入右子节点,无需分裂):[10]/   \[5,6] [12,20]6. 插入30(右子节点分裂):[10,20]/   |   \[5,6] [12] [30]7. 插入7(左子节点分裂,触发根节点更新):[6,10,20]/   |   |   \[5] [7] [12] [30]

三、B树的应用场景

场景应用原理
数据库索引

B树保持数据有序,支持高效范围查询(如MySQL的InnoDB引擎使用B+树变种)

  • B树在数据库中被广泛用于索引结构,以加速数据的检索速度。由于B树能够保持平衡性,使得所有叶子节点到根节点的路径长度相近,从而保证了搜索的效率。
  • 在数据库中,索引是帮助快速查找数据的数据结构。通过B树,数据库系统可以快速定位数据的存储位置,提高数据访问的速度。
文件系统

NTFS、ReiserFS等文件系统用B树管理文件和目录的元数据

  • B树也被广泛应用于文件系统中,用于实现目录结构和文件分配表,以管理文件的存储和访问。
  • 文件系统通常需要频繁地进行查找和检索文件,而B树的平衡性和高度平衡特性使得这一过程更为高效。
  • B树能够减少磁盘I/O操作的次数,从而显著提高数据存取的效率。这对于大型文件系统来说尤为重要。
内存受限环境通过减少树高度降低内存访问次数
网络路由表快速查找IP地址对应的路由信息
外部排序

在外部排序中,由于数据量太大,无法一次性装入内存,因此需要使用磁盘等外部存储设备。B树可以作为外部排序过程中的一个关键数据结构,帮助实现多路归并排序,提高排序的效率。

四、C语言实现B树及示例

#include <stdio.h>
#include <stdlib.h>
#define M 3  // B树阶数
#define MAX_KEYS (M-1)
#define MIN_KEYS (M/2 - 1)typedef struct BTreeNode {int keys[MAX_KEYS];struct BTreeNode *children[M];int num_keys;int is_leaf;
} BTreeNode;BTreeNode* create_node(int is_leaf) {BTreeNode* node = (BTreeNode*)malloc(sizeof(BTreeNode));node->num_keys = 0;node->is_leaf = is_leaf;for (int i = 0; i < M; i++) node->children[i] = NULL;return node;
}void split_child(BTreeNode *parent, int index) {BTreeNode *child = parent->children[index];BTreeNode *new_node = create_node(child->is_leaf);// 新节点获取后半部分键new_node->num_keys = MIN_KEYS;for (int i = 0; i < MIN_KEYS; i++) new_node->keys[i] = child->keys[i + MIN_KEYS + 1];// 移动子节点指针(若非叶子节点)if (!child->is_leaf) {for (int i = 0; i <= MIN_KEYS; i++)new_node->children[i] = child->children[i + MIN_KEYS + 1];}child->num_keys = MIN_KEYS;// 将中间键提升到父节点for (int i = parent->num_keys; i > index; i--)parent->children[i + 1] = parent->children[i];parent->children[index + 1] = new_node;for (int i = parent->num_keys - 1; i >= index; i--)parent->keys[i + 1] = parent->keys[i];parent->keys[index] = child->keys[MIN_KEYS];parent->num_keys++;
}void insert_non_full(BTreeNode *node, int key) {int i = node->num_keys - 1;if (node->is_leaf) {while (i >= 0 && key < node->keys[i]) {node->keys[i + 1] = node->keys[i];i--;}node->keys[i + 1] = key;node->num_keys++;} else {while (i >= 0 && key < node->keys[i]) i--;i++;if (node->children[i]->num_keys == MAX_KEYS) {split_child(node, i);if (key > node->keys[i]) i++;}insert_non_full(node->children[i], key);}
}void insert(BTreeNode **root, int key) {if ((*root)->num_keys == MAX_KEYS) {BTreeNode *new_root = create_node(0);new_root->children[0] = *root;*root = new_root;split_child(new_root, 0);insert_non_full(new_root, key);} else {insert_non_full(*root, key);}
}// 打印B树(中序遍历)
void print_tree(BTreeNode *node, int level) {printf("Level %d: ", level);for (int i = 0; i < node->num_keys; i++)printf("%d ", node->keys[i]);printf("\n");if (!node->is_leaf) {for (int i = 0; i <= node->num_keys; i++)if (node->children[i]) print_tree(node->children[i], level + 1);}
}int main() {BTreeNode *root = create_node(1); // 初始为叶子节点int keys[] = {10, 20, 5, 6, 12, 30, 7, 17};for (int i = 0; i < sizeof(keys)/sizeof(int); i++) {insert(&root, keys[i]);printf("After inserting %d:\n", keys[i]);print_tree(root, 0);printf("----------------\n");}return 0;
}

 五、代码执行结果说明

输出示例(部分):

After inserting 10:
Level 0: 10 
----------------
After inserting 20:
Level 0: 10 20 
----------------
After inserting 5:
Level 0: 10 
Level 1: 5 
Level 1: 20 
----------------
...

代码特性:

  1. 动态分裂:当节点满时自动分裂

  2. 递归插入:通过insert_non_full函数确保插入路径上的节点都有空间

  3. 层级打印:可视化展示B树结构

六、应用实例:文件系统目录索引

typedef struct {char filename[256];long offset;
} FileRecord;// 在B树节点中存储文件记录
BTreeNode* create_file_index() {return create_node(1); // 创建叶子节点
}void index_file(BTreeNode **root, const char *filename, long offset) {int hash_key = 0;for (int i = 0; filename[i]; i++) hash_key += filename[i];insert(root, hash_key); // 实际应存储FileRecord结构
}

该实现可用于构建文件系统索引,通过文件名哈希快速定位文件物理位置。

七、总结

综上所述,B树作为一种高效的数据结构,在数据库系统、文件系统以及外部排序等领域具有广泛的应用前景。其平衡性和高度平衡的特性使得B树在处理大量数据时能够保持稳定的性能,从而满足了各种复杂和多样化的数据存储和检索需求。

相关文章:

B树详解及其C语言实现

目录 一、B树的基本原理 二、B树操作过程图形化演示 三、B树的应用场景 四、C语言实现B树及示例 五、代码执行结果说明 六、应用实例&#xff1a;文件系统目录索引 七、总结 一、B树的基本原理 B树&#xff08;B-Tree&#xff09; 是一种自平衡的树数据结构&#xff0c;…...

【Go语言快速上手】第二部分:Go语言进阶

文章目录 并发编程goroutine&#xff1a;创建和调度 goroutinechannel&#xff1a;无缓冲 channel、有缓冲 channel、select 语句无缓冲 channel有缓冲 channelselect 语句 sync 包&#xff1a;Mutex、RWMutex、WaitGroup 等同步原语Mutex&#xff1a;互斥锁RWMutex&#xff1a…...

ARM64 Linux 内核学习指南:从基础到实践

前言 ARM64 作为当今主流的处理器架构&#xff0c;被广泛应用于移动设备、嵌入式系统和服务器领域。学习 ARM64 在 Linux 内核中的实现&#xff0c;不仅有助于深入理解操作系统底层机制&#xff0c;还能提升在内核开发、驱动编写、虚拟化等领域的专业能力。 本指南面向对 Lin…...

零基础都可以本地部署Deepseek R1

文章目录 一、硬件配置需求二、详细部署步骤1. 安装 Ollama 工具2. 部署 DeepSeek-R1 模型3. API使用4. 配置图形化交互界面&#xff08;可选&#xff09;5. 使用与注意事项 一、硬件配置需求 不同版本的 DeepSeek-R1 模型参数量不同&#xff0c;对硬件资源的要求也不尽相同。…...

掌握Spring @SessionAttribute:跨请求数据共享的艺术

SessionAttribute注解在Spring中的作用&#xff0c;就像是一个“数据中转站”。 在Web应用中&#xff0c;我们经常需要在多个请求之间共享数据。比如&#xff0c;用户登录后&#xff0c;我们需要在多个页面或请求中保持用户的登录状态。这时&#xff0c;SessionAttribute注解就…...

视频采集卡接口

采集卡的正面有MIC IN、LINE IN以及AUDIO OUT三个接口&#xff0c; MIC IN为麦克风输入&#xff0c;我们如果要给采集到的视频实时配音或者是在直播的时候进行讲解&#xff0c;就可以在这里插入一个麦克风&#xff0c; LINE IN为音频线路输入&#xff0c;可以外接播放背景音乐…...

64【32与64位程序的区别】

很多人可能有一个观念&#xff0c;那就是64位的程序NB&#xff0c;有技术含量&#xff0c;但是要说nb在哪&#xff0c;很多人又说不上来&#xff0c;本节来对这个问题做一个探讨 下图中左边的是加载的64程序&#xff0c;右边的是32位程序&#xff0c; 在上一节课我们已经理解…...

ai智能DeepSeek 在 Cursor 中的配置与应用实践

DeepSeek 是一款高效的深度搜索引擎&#xff0c;能够为开发者提供更智能、更精准的搜索体验。在数据量大、查询复杂的场景中&#xff0c;DeepSeek 能够帮助提升查询的响应速度和精确度。本文将介绍 DeepSeek 在 Cursor 中的配置与应用&#xff0c;帮助开发者理解如何在实际开发…...

Deepseek的起源与发展

文章目录 前言一、Deepseek的起源二、DeepSeek的发展脉络三、Deepseek的突破与优势(1)功能强大:核心能力与应用场景(2)性能优势:效率与效果的革命性提升四、Deepseek开源引发关注前言 DeepSeek 在网络安全领域带来的新机遇,DeepSeek 从崭露头角到引领 AI 领域的重大变革,已…...

ubuntu conda运行kivy时报“No matching FB config found”

错误描述&#xff1a;本人使用ubuntu自带的python环境运行kivy是没有问题的&#xff0c;就是在使用conda时发生了错误&#xff0c;去网上寻找报错原因&#xff0c;却一直没有头绪&#xff08;这个问题有诸多问题导致的&#xff0c;不敢说用我的这个方法100%能好&#xff09; 1…...

1-1二分查找

二分查找 1 基础版1.1 算法描述1.2 算法流程图1.3 算法实现1.3.1 Java实现 2 改动版2.1 算法描述2.2 算法流程图2.3 算法实现2.3.1 Java实现 2.4 改进点分析2.4.1 区间定义差异2.4.2 核心改进原理2.4.3 数学等价性证明 3 平衡版3.1 算法描述3.2 算法流程图3.3 算法实现3.3.1 Ja…...

【如何掌握CSP-J 信奥赛中的深搜算法】

CSP-J 信奥赛中的深搜&#xff08;深度优先搜索&#xff09;算法是一个重要知识点&#xff0c;以下是一些学习深搜算法的建议&#xff1a; 理解基础概念 定义与原理&#xff1a;深度优先搜索是一种用于遍历或搜索图、树等数据结构的算法。它从起始节点开始&#xff0c;沿着一条…...

Unity笔试常考

线程同步的几种方式 1.信号量pv操作 2.互斥加锁 3.条件变量 五层网络协议指的是哪五层 1.应用层 2.运输层 3.网络层 4.链路层 5.物理层 TCP和UDP区别 tcp 面向连接&#xff0c;保证发送顺序&#xff0c;速度慢&#xff0c;必须在线&#xff0c;三次握手&#xff0c;4次挥手…...

知识图谱智能应用系统:基于人工智能的知识提取架构

在知识图谱智能应用系统中,知识提取是将非结构化数据(如文本、文档)转化为结构化知识的关键步骤。通过人工智能技术,系统能够自动识别文本中的实体、关系、属性和事件,并将其转化为可用于知识图谱构建的三元组数据。以下是对知识提取架构的详细描述,包括环境准备、数据标…...

Qt:Qt基础介绍

目录 Qt背景介绍 什么是Qt Qt的发展史 Qt支持的平台 Qt版本 Qt的优点 Qt的应用场景 Qt的成功案例 Qt的发展前景及就业分析 Qt背景介绍 什么是Qt Qt是⼀个跨平台的C图形用户界面应用程序框架。它为应用程序开发者提供了建立艺术级图形界面所需的所有功能。它是完全面向…...

【deepSeek R1】Ollama 更改模型安装位置 以及应用安装位置

【deepSeek R1】Ollama 更改模型安装位置 以及应用安装位置 本地版部署deepSeek R1 可以参考文章 3分钟教你搭建属于自己的本地大模型 DeepSeek R1 Ollama 是一个开源工具&#xff0c;旨在帮助用户轻松在本地计算机上运行、部署和管理大型语言模型&#xff08;LLMs&#xff09;…...

让office集成deepseek,支持office和WPS办公软件!(体验感受)

导读 AIGC:AIGC是一种新的人工智能技术&#xff0c;它的全称是Artificial Intelligence Generative Content&#xff0c;即人工智能生成内容。 它是一种基于机器学习和自然语言处理的技术&#xff0c;能够自动产生文本、图像、音频等多种类型的内容。这些内容可以是新闻文章、…...

DKG(Distributed Key Generation)协议

一、DKG是什么 DKG(分布式密钥生成)提供了一种去中心化的方法,使各个参与方在不相互信任的情况下生成共享密钥,以确保安全通信和多方参与的机密性。 DKG技术的关键思想是使用多方计算(secure multiparty computation)和秘钥共享(secret sharing)的概念。 秘钥共享 则…...

动态规划问题——青蛙跳台阶案例分析

问题描述&#xff1a; 一只青蛙要跳上n级台阶&#xff0c;它每次可以跳 1级或者2级。问&#xff1a;青蛙有多少种不同的跳法可以跳完这些台阶&#xff1f; 举个例子&#xff1a; 假设台阶数 n 3 &#xff0c;我们来看看青蛙有多少种跳法。 可能的跳法&#xff1a; 1. 跳1级…...

Spring(26) spring-security-oauth2 官方表结构解析

目录 一、什么是 spring-security-oauth2&#xff1f;二、spring-security-oauth2 的表结构2.1 oauth_client_details 客户端详细信息表2.2 oauth_access_token 认证授权Token记录表2.3 oauth_refresh_token 刷新授权Token记录表2.4 oauth_code 授权Code记录表 一、什么是 spri…...

MySQL 数据库编程-C++

目录 1 数据库基本知识 1.1 MYSQL常见命令 1.2 SQL注入 1.3 ORM框架 1 数据库基本知识 MySQL 为关系型数据库(Relational Database Management System), 这种所谓的"关系型"可以理解为"表格"的概念, 一个关系型数据库由一个或数个表格组成&#xff1a…...

【大数据技术】搭建完全分布式高可用大数据集群(Flume)

搭建完全分布式高可用大数据集群(Flume) apache-flume-1.11.0-bin.tar.gz注:请在阅读本篇文章前,将以上资源下载下来。 写在前面 本文主要介绍搭建完全分布式高可用集群 Flume 的详细步骤。 注意: 统一约定将软件安装包存放于虚拟机的/software目录下,软件安装至/opt目…...

疯狂前端面试题(二)

一、Webpack的理解 Webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。Webpack 能够将各种资源&#xff08;JavaScript、CSS、图片、字体等&#xff09;视为模块&#xff0c;并通过依赖关系图将这些模块打包成一个或多个最终的输出文件&#xff08;通常是一个或几个…...

kafka专栏解读

kafka专栏文章的编写将根据kafka架构进行编写&#xff0c;即先编辑kafka生产者相关的内容&#xff0c;再编写kafka服务端的内容&#xff08;这部分是核心&#xff0c;内容较多&#xff0c;包含kafka分区管理、日志存储、延时操作、控制器、可靠性等&#xff09;&#xff0c;最后…...

深入探究 C++17 std::is_invocable

文章目录 一、引言二、std::is_invocable 概述代码示例输出结果 三、std::is_invocable 的工作原理简化实现示例 四、std::is_invocable 的相关变体1. std::is_invocable_r2. std::is_nothrow_invocable 和 std::is_nothrow_invocable_r 五、使用场景1. 模板元编程2. 泛型算法 …...

OpenCV:图像修复

目录 简述 1. 原理说明 1.1 Navier-Stokes方法&#xff08;INPAINT_NS&#xff09; 1.2 快速行进方法&#xff08;INPAINT_TELEA&#xff09; 2. 实现步骤 2.1 输入图像和掩膜&#xff08;Mask&#xff09; 2.2 调用cv2.inpaint()函数 2.3 完整代码示例 2.4 运行结果 …...

【项目日记(四)】thread cache 层

前言 前面我们对整个项目的框架进行了介绍&#xff0c;本期开始我们将进行第一层线程缓存层(thread cache)的详细介绍与实现。 目录 前言 一、thread cache 的整体设计 二、内存对齐规则和哈希映射关系 2.1 如何对齐&#xff1f; 2.2 这样设计对齐规则的好处&#xff1f…...

人工智能图像分割之Mask2former源码解读

环境搭建: (1)首先本代码是下载的mmdetection-2022.9的,所以它的版本要配置好,本源码配置例如mmcv1.7,python3.7,pytorch1.13,cuda11.7。pytorch与python,cuda版本匹配可参考&#xff1a;https://www.jb51.net/python/3308342lx.htm。 (2)还有一个是先要安装一个vs2022版本或…...

uniapp 编译生成鸿蒙正式app步骤

1&#xff0c;在最新版本DevEco-Studio工具新建一个空项目并生成p12和csr文件&#xff08;构建-生成私钥和证书请求文件&#xff09; 2&#xff0c;华为开发者平台 根据上面生成的csr文件新增cer和p7b文件&#xff0c;分发布和测试 3&#xff0c;在最新版本DevEco-Studio工具 文…...

2024最新版Java面试题及答案,【来自于各大厂】

发现网上很多Java面试题都没有答案&#xff0c;所以花了很长时间搜集整理出来了这套Java面试题大全~ 篇幅限制就只能给大家展示小册部分内容了&#xff0c;需要完整版的及Java面试宝典小伙伴点赞转发&#xff0c;关注我后在【翻到最下方&#xff0c;文尾点击名片】即可免费获取…...