[C++][数据结构][B-树][上]详细讲解

news2025/1/16 0:09:47

目录

  • 0.常见的搜索结构
  • 1.B树概念
  • 2.B-树的插入分析
    • 1.流程分析
    • 2.插入过程总结


0.常见的搜索结构

种类数据格式时间复杂度
顺序查找无要求 O ( N ) O(N) O(N)
二分查找有序 O ( l o g 2 N ) O(log_2 N) O(log2N)
二叉搜索树无要求 O ( N ) O(N) O(N)
二叉平衡树无要求 O ( l o g 2 N ) O(log_2 N) O(log2N)
哈希无要求 O ( 1 ) O(1) O(1)
  • 以上结构适合用于数据量相对不是很大,能够一次性存放在内存中,进行数据查找的场景

    • 如果数据量很大,比如有100G数据,无法一次放进内存中,那就只能放在磁盘上了
  • 如果放在磁盘上,又需要搜索某些数据,那么如何处理呢?

    • 可以考虑将存放关键字及其映射的数据的地址放到一个内存中的搜索树的节点中

    • 要访问数据时,先取这个地址去磁盘访问数据

      请添加图片描述

  • 使用平衡二叉树的缺陷:

    • 平衡二叉树搜索树的高度是 l o g 2 N log_2N log2N,这个查找次数在内存中是很快的
    • 但是当数据都在磁盘中时,访问磁盘速度很慢
      • 在数据量很大时, l o g 2 N log_2N log2N次的磁盘访问,是一个难以接受的结果
  • 使用哈希表的缺陷:

    • 哈希表的效率很高是 O ( 1 ) O(1) O(1)
    • 但是一些极端场景下某个位置冲突很多,导致访问次数剧增,也是难以接受的
      • 极端场景下冲突非常严重,效率下降很多
  • 那如何加速对数据的访问呢?

    1. 提高IO的速度(SSD相比传统机械硬盘快了不少,但是还是没有得到本质性的提升)
    2. 降低树的高度 – 多叉树平衡树
  • 为什么硬盘IO慢?
    请添加图片描述


1.B树概念

  • B树是一种适合外查找的树,它是一种平衡的多叉树
    • 后面有一个改进版本B+树
  • 一棵m阶(m>2)的B树,是一棵平衡的M路平衡搜索树,可以是空树或者满足以下性质:
    • 根节点至少有两个孩子
    • 每个分支结点都包含k-1个关键字和k个孩子,其中 c e i l ( m / 2 ) < = k < = m ceil(m/2) <= k <= m ceil(m/2)<=k<=m
      • 孩子比关键字保持多一个的关系
      • TIPS:ceil()是向上取整函数
    • 每个叶子结点都包含k-1个关键字,其中 c e i l ( m / 2 ) < = k < = m ceil(m/2) <= k <= m ceil(m/2)<=k<=m
    • 所有的叶子结点都在同一层
    • 每个结点中的关键字从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域划分
    • 每个结点的结构为: ( n , A 0 , K 1 , A 1 , K 2 , A 2 , … , K n , A n ) (n,A_0,K_1,A_1,K_2,A_2,… ,K_n,A_n) (nA0K1A1K2A2KnAn)
      • K i ( 1 ≤ i ≤ n ) K_i(1≤i≤n) Ki(1in)关键字,且 K i < K i + 1 ( 1 ≤ i ≤ n − 1 ) K_i<K_{i+1}(1≤i≤n-1) Ki<Ki+1(1in1)
      • A i ( 0 ≤ i ≤ n ) A_i(0≤i≤n) Ai(0in)为**指向子树根结点的指针**,且 A i A_i Ai所指子树所有结点中的关键字均小于 K i + 1 K_{i+1} Ki+1
      • n为结点中关键字的个数,满足 c e i l ( m / 2 ) − 1 ≤ n ≤ m − 1 ceil(m/2)-1≤n≤m-1 ceil(m/2)1nm1
  • B树的性质保证了B树是天然平衡的
    • 只会向右和向上生长
      • 只有在根结点分裂时,才会增加一层
    • 新插入的结点,一定是在叶子插入
      • 叶子没有孩子,不影响关键字和孩子的关系
    • 叶子节点满了,分裂出一个兄弟,提取中位数,向父亲插入一个值和一个孩子

2.B-树的插入分析

1.流程分析

  • 为了简单起见,假设 M = 3 M = 3 M=3,即三叉树,每个节点中存储两个数据,两个数据可以将区间分割成三个部分,因此节点应该有三个孩子,为了后续实现简单起见,节点的结构如下

    • 注意:孩子永远比数据多一个

      请添加图片描述

  • 用序列{53, 139, 75, 49, 145, 36, 101}构建B树的过程如下:

  • 插入75的过程如下

    1. 按照插入排序思想,将75插入到序列中

    2. 插入后该结点不满足情况,需要对该结点进行分裂

      请添加图片描述

  • 分裂结点:关键字的数量等于M,则满了,满了就分裂出一个兄弟结点,分裂一半的值和孩子给兄弟

    1. 找到结点数据域的中间位置
    2. 给一个新结点,将中间位置的右边数据搬移到新结点中
    3. 将中间位置数据搬移到父结点中
    4. 将结点连接好
      请添加图片描述
  • 插入49,145的过程如下

    1. 找到该元素的插入位置(索要插入结点pCur)
    2. 按照插入排序思想将结点插入到该结点(pcur)的合适位置
    3. 检测该结点是否满足B树的性质
      • 满足:插入结束
      • 不满足:对该结点进行分裂
        请添加图片描述
  • 插入36的过程如下

    • 插入完成后,该结点违反B-树性质,需要对pCur进行分裂
      1. 找到中间位置

      2. 将中间位置右侧元素搬移到新结点中

      3. 将中间位置数据49以及新生成的结点往parent中继续插入

        请添加图片描述

  • 插入101的过程如下:

    1. 先在B-树种找到该结点的插入位置
    2. 按照插入排序思想将该结点插入到pCur结点中
    3. 检测该结点是否满足B树的性质,该结点中存放元素个数是否小于M
      • 小于M:插入完成
      • 等于M:需要对该结点进行分裂
        • 找中间位置,将中间位置右侧数据搬移到新结点中

        • 将中间位置数据以及新结点往pCur双亲中继续插入

          请添加图片描述

2.插入过程总结

  1. 如果树为空,直接插入新节点中,该节点为树的根节点
  2. 树非空,找待插入元素在树中的插入位置
    • 注意:找到的插入节点位置一定在叶子节点中
  3. 检测是否找到插入位置
    • 假设树中的key唯一,即该元素已经存在时则不插入
  4. 按照插入排序的思想将该元素插入到找到的节点中
  5. 检测该节点是否满足B-树的性质
    • 即:该节点中的元素个数是否等于M,如果小于则满足
  6. 如果插入后节点不满足B树的性质,需要对该节点进行分裂:
    • 申请新节点
    • 找到该节点的中间位置
    • 将该节点中间位置右侧的元素以及其孩子搬移到新节点中
    • 将中间位置元素以及新节点往该节点的双亲节点中插入,即继续(4)
  7. 如果向上已经分裂到根节点的位置,插入结束

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【计算机网络仿真】b站湖科大教书匠思科Packet Tracer——实验5 交换机的自学习算法

一、实验目的 1.验证交换机的自学习算法&#xff1b; 2.了解交换机对帧的过滤特性&#xff1b; 3.学习交换机如何登记接收到的数据包&#xff1b; 4.学习交换机如何转发数据包&#xff08;明确转发&#xff0c;盲目转发&#xff0c;丢弃&#xff09;。 二、实验要求 1.使用Cisc…

自动化办公04 使用pyecharts制图

目录 一、柱状图 二、折线图 三、饼图 四、地图 1. 中国地图 2. 世界地图 3. 省会地图 五、词云 Pyecharts是一个用于数据可视化的Python库。它基于Echarts库&#xff0c;可以通过Python代码生成各种类型的图表&#xff0c;如折线图、柱状图、饼图、散点图等。 Pyecha…

养车小程序系统源码,汽修源码,仿途虎养车系统源码,车辆保养小程序系统

用户端&#xff0b;商家端&#xff0b;师傅端 功能介绍: 支持下单上门服务、到店核销&#xff0c;支持单独选择项目、 也支持选择服务人员、和选择门店多种下单方式&#xff0c; 支持上门服务和到店核销两种服务方式&#xff0c;支持自营和多商家联营两种运营模式&#xff…

静态路由(Static-Route)-Cisco

路由&#xff08;Route&#xff09; 世界上数亿的计算机大海 通过路由将世界连接 路由连接LAN、WAN、MAN&#xff0c;也连接世界 路由的工作 路由器将大块信息分解为小数据包 以实现可靠和高效的传输 过程称为“反汇编”和“封装数据有效负载” 路由表是一种逻辑数据结构…

Linux 服务管理(待更)

服务(service)本质就是进程&#xff0c;但是是运行在后台的&#xff0c;通常都会监听某个端口&#xff0c;等待其它程序的请求&#xff0c;比如(mysqld , sshd防火墙等)&#xff0c;因此又称为守护进程。 比如通过xshell进行连接的时候&#xff0c;需要输入的端口号就是通过守护…

PyTorch梯度直通反传

有时我们想在层的输出端放置一个阈值函数。这可能出于多种原因。其中之一是我们想将激活总结为二进制值。这种激活的二值化在自编码器中很有用。 然而&#xff0c;阈值化在反向传播过程中会带来问题&#xff1a;阈值函数的导数为零。这种梯度的缺乏导致我们的网络无法学习任何…

CSDN图片居中、左对齐、右对齐、大小设置

图片居中、左对齐、右对齐 ![在这里插入图片描述](https://img-blog.csdnimg.cn/99dc1072e8f1471990b700e1c85d301a.jpeg#pic_center) 大小设置 空格400x150 空格30%x # 长400 宽200 ![在这里插入图片描述](https://img-blog.csdnimg.cn/99dc1072e8f1471990b700e1c85d301a.…

hive on spark 的架构和常见问题 - hive on spark 使用的是 yarn client 模式还是 yarn cluster 模式?

hive on spark 的架构和常见问题 - hive on spark 使用的是 yarn client 模式还是 yarn cluster 模式&#xff1f; 1. 回顾下 spark 的架构图和部署模式 来自官方的经典的 spark 架构图如下&#xff1a; 上述架构图&#xff0c;从进程的角度来讲&#xff0c;有四个角色/组件&…

opencascade AIS_InteractiveContext源码学习3 highlighting management 对象高亮管理

AIS_InteractiveContext 前言 交互上下文&#xff08;Interactive Context&#xff09;允许您在一个或多个视图器中管理交互对象的图形行为和选择。类方法使这一操作非常透明。需要记住的是&#xff0c;对于已经被交互上下文识别的交互对象&#xff0c;必须使用上下文方法进行…

TugraphDB:探索图数据库新境界

TugraphDB&#xff1a;释放图数据的全部潜能- 精选真开源&#xff0c;释放新价值。 概览 TugraphDB是支付宝背后的分布式图数据库。该项目是由蚂蚁集团和清华大学共同研发的高性能分布式图数据库&#xff0c;支持事务处理、TB 级大容量、低延迟查找和快速图分析等功能。专为处…

安卓系统安装linux搭建随手服务器termux平替软件介绍

引言 旧手机丢可惜&#xff0c;可以用ZeroTermux&#xff08;一款代替termux&#xff09;的超级终端&#xff0c;来模拟Linux&#xff08;甚至你可以模拟Win&#xff0c;只要性能够用&#xff09; ps&#xff1a;此软件只是termux的增强版&#xff0c;相当于增加右边菜单&…

第N5周:调用Gensim库训练Word2Vec模型

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制&#x1f680; 文章来源&#xff1a;K同学的学习圈子 目录 本周任务: 1.安装Gensim库 2.对原始语料分词 3.停用词 4.训练Woed2Vec模型 …

单阶段目标检测--NMS

目录 一、概念: 二、算法过程 三、代码实现 一、概念: 在目标检测的初始结果中&#xff0c;同一个物体&#xff0c;可能对应有多个边界框 &#xff08;bounding box&#xff0c;bb&#xff09;&#xff0c;这些边界框通常相互重叠。如何从中选择一个最合适 的&#xff08;也就…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 披萨大作战(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…

1 UC

1 UC 1、环境变量2、环境变量表3、错误处理4、库文件4.1 静态库4.2 动态库4.3 动态库的动态加载 5、虚拟地址 1、环境变量 什么是环境变量&#xff1f; 每个进程都有一张自己的环境变量表&#xff0c;表中的每个条目都是形如“键值”形式的环境变量。进程可以通过环境变量访问…

opencascade AIS_InteractiveContext源码学习4 object local transformation management

AIS_InteractiveContext 前言 交互上下文&#xff08;Interactive Context&#xff09;允许您在一个或多个视图器中管理交互对象的图形行为和选择。类方法使这一操作非常透明。需要记住的是&#xff0c;对于已经被交互上下文识别的交互对象&#xff0c;必须使用上下文方法进行…

数据结构4---串

一、字符串暴力匹配 要注意的就是i与j的回溯&#xff0c;通过不断移动主串的指针&#xff0c;时间复杂度高 #include <stdio.h> #include <stdlib.h>typedef struct String {char* data;int len; }String;String* initString() {String* s (String*)malloc(sizeo…

分布式理论与设计 四、分布式系统设计策略

在分布式环境下&#xff0c;有几个问题是普遍关心的&#xff1a; 如何检测当前节点还活着&#xff1f;如何保障高可用&#xff1f;容错处理负载均衡 1.心跳检测 在分布式环境中&#xff0c;我们提及过存在非常多的节点&#xff08;Node&#xff09;。那么就有一个非常重要的…

c++ 编译过程杂记等

开篇一张图。 编译器 把我们的代码翻译成机器语言 ​ gcc编译程序的过程 gcc编译程序主要经过四个过程&#xff1a; 四个过程说明&#xff1a; ​ 预处理实际上是将头文件、宏进行展开。 编译阶段&#xff0c;gcc调用不同语言的编译器&#xff0c;例如c语言调用编译器ccl…

OpenTenBase入门

什么是OpenTenBase OpenTenBase 是一个提供写可靠性&#xff0c;多主节点数据同步的关系数据库集群平台。你可以将 OpenTenBase 配置一台或者多台主机上&#xff0c; OpenTenBase 数据存储在多台物理主机上面。数据表的存储有两种方式&#xff0c; 分别是 distributed 或者 re…