数据结构(AVL树、B-Tree、B+Tree)
AVL树
AVL树是一种自平衡的二叉搜索树,它的特点是每个节点的左子树和右子树的高度差(平衡因子)的绝对值不超过1。这种平衡性保证了AVL树在进行查找、插入和删除操作时都能保持较高的效率。
平衡因子
在AVL树中,每个节点都维护一个额外的信息,即平衡因子。平衡因子定义为该节点的左子树高度减去右子树高度(或右子树高度减去左子树高度,但通常以前者为准)。平衡因子的值只能为-1、0或+1。
旋转操作
当在AVL树上进行插入或删除操作时,可能会导致某些节点的平衡因子超出允许的范围(即绝对值大于1)。为了恢复平衡,AVL树采用旋转操作来调整节点的位置。旋转操作包括单旋转和双旋转两种类型:
- 单旋转:
- 右旋(LL旋转):当某个节点的左子节点的左子树上插入新节点,导致该节点的平衡因子变为+2时,进行右旋转操作。右旋转以该节点为根的子树,将其左子节点提升为新的根节点,该节点则成为新根节点的右子节点。
- 左旋(RR旋转):与右旋类似,但方向相反。当某个节点的右子节点的右子树上插入新节点,导致该节点的平衡因子变为-2时,进行左旋操作。
- 双旋转:
- 先左后右旋转(LR旋转):当某个节点的左子节点的右子树上插入新节点,导致该节点的平衡因子变为+2,且其左子节点的平衡因子为+1时,先进行左旋操作调整左子树,再对根节点进行右旋操作。
- 先右后左旋转(RL旋转):与LR旋转类似,但方向相反。当某个节点的右子节点的左子树上插入新节点,导致该节点的平衡因子变为-2,且其右子节点的平衡因子为-1时,先进行右旋操作调整右子树,再对根节点进行左旋操作。
AVL树操作
- 插入操作:
- 将新节点按照二叉搜索树的规则插入到AVL树中。
- 从插入点开始,向上回溯到根节点,检查每个节点的平衡因子。
- 若某节点的平衡因子超出范围,则根据具体情况进行旋转操作以恢复平衡。
- 删除操作:
- 找到要删除的节点,并将其向下旋转成一个叶子节点(若该节点不是叶子节点)。
- 直接删除该叶子节点。
- 从删除点开始,向上回溯到根节点,检查每个节点的平衡因子。
- 若某节点的平衡因子超出范围,则根据具体情况进行旋转操作以恢复平衡。
- 查找操作:
- AVL树的查找操作与二叉搜索树相同,利用平衡性保证查找效率为O(log n)。
AVL树的优势与应用
AVL树的优势在于其严格的平衡性保证了所有基本操作(查找、插入、删除)的时间复杂度均为O(log n)。这使得AVL树在需要频繁进行这些操作的场景中表现出色,如数据库索引、内存管理等。然而,AVL树在插入和删除操作时需要频繁进行旋转操作以维持平衡性,这可能会增加一些额外的开销。尽管如此,AVL树仍然是一种高效且广泛应用的自平衡二叉搜索树。
B-Tree
B-Tree(Balanced Tree),即B树,是一种自平衡的树形数据结构,专为磁盘和其他直接访问的辅助存储设备而设计,广泛应用于数据库和文件系统中。以下是B-Tree原理的详细解释:
基本概念
- 多路搜索树:B树是一种多路搜索树,也被称为平衡多路查找树。与二叉搜索树不同,B树的每个节点可以拥有多个子节点和键值。
- 键值:节点中的键值按照升序排列,并作为子树的分隔键。
- 子节点指针:每个键值将节点分割成多个子树,每个子树由一个子节点指针指向。
- 叶子节点:叶子节点不包含键值对应的记录,但通常包含指向实际记录的指针。
- 阶(Order)或分支因子(Branch Factor):通常用字母m表示,它定义了节点可以拥有的最大子节点数(即m个子节点)。因此,一个节点最多可以有m-1个键值。非根节点至少需要有⌈m/2⌉个子节点,以保持树的平衡。
性质
- 高度平衡:B树是一种高度平衡的数据结构,所有叶子节点都位于同一层。这种平衡性确保了所有查找、插入和删除操作的时间复杂度都是O(log n),其中n是树中元素的数量。
- 有序性:节点中的键值按照从小到大的顺序排列,这有助于在查找过程中快速定位目标数据。
操作
- 搜索:搜索操作从根节点开始,通过比较要查找的键与节点中的键,决定是继续在左子树还是右子树中搜索。如果键等于节点中的某个键,则搜索成功;如果键小于节点中的所有键,则搜索左子树;如果键大于节点中的所有键,则搜索右子树。这个过程一直持续到找到目标键或到达叶子节点为止。
- 插入:插入操作首先找到合适的叶子节点,然后将新键插入该节点。如果插入后节点中的键的数量超过了m-1,则节点会分裂成两个节点,并将中间的键提升到父节点。如果父节点也满了,则继续向上分裂,直到根节点。如果根节点也分裂,则创建一个新的根节点,并包含分裂出的中间键。
- 删除:删除操作首先找到包含要删除键的节点,并从节点中移除该键。如果删除后节点中的键的数量少于要求的最小数量(⌈m/2⌉ - 1),则需要重新分配或合并节点。重新分配通常是从兄弟节点借键,合并则是将当前节点与兄弟节点合并,并可能将父节点中的键下移。如果删除操作导致根节点中只有一个键,且没有子节点,则树的高度会减一。
应用
- 数据库索引:B树通过减少磁盘访问次数,显著提高了数据库查询的效率。在数据库中,索引是帮助快速查找数据的数据结构。B树作为索引结构,能够支持高效的查找、插入和删除操作。
- 文件系统:B树也常用于文件系统中,用于快速定位文件的存储位置。通过B树,文件系统可以高效地管理元数据(如文件名、文件大小、创建时间等),并快速访问文件数据。
- 外部排序:在外部排序中,由于数据量太大,无法一次性装入内存,因此需要使用磁盘等外部存储设备。B树可以作为外部排序过程中的一个关键数据结构,帮助实现多路归并排序,提高排序的效率。
B+Tree
B+Tree的原理主要基于其数据结构和查找、插入、删除等操作的特点。以下是对B+Tree原理的详细解释:
数据结构
B+Tree是B树(Balanced Tree)的一种变形,是一种多路平衡查找树。在B+Tree中,数据被存储在叶子节点,而非叶子节点仅用于索引,不存储实际数据。这种结构使得B+Tree在查找、插入和删除操作时具有更高的效率。
-
节点类型:
- 根节点:B+Tree的起始节点,用于引导查找过程。
- 内部节点(非叶子节点):仅包含索引信息和指向子节点的指针,不存储实际数据。
- 叶子节点:存储实际数据和指向下一个叶子节点的指针,形成有序链表结构。
-
节点结构:
- 每个节点包含一定数量的关键字(key)和指针(pointer)。
- 关键字按升序排列,指针指向包含相应关键字的子节点或叶子节点。
-
节点容量:
- 每个节点有一个最大容量,当节点中的关键字数量达到最大容量时,会发生节点分裂。
查找操作
-
过程:
- 从根节点开始,根据关键字进行二分查找。
- 找到匹配的关键字所在的指针,递归地进入子节点进行查找。
- 最终到达叶子节点,在叶子节点上进行二分查找或顺序遍历找到目标数据。
-
特点:
- B+Tree的查找过程稳定且高效,因为所有叶子节点都在同一层,树的高度较低。
- 叶子节点之间的有序链表结构使得范围查询和顺序遍历更加高效。
插入操作
-
过程:
- 找到应插入叶子节点的位置。
- 将新关键字插入叶子节点。
- 如果叶子节点已满,则进行节点分裂,将部分关键字和指针移动到新的节点,并更新父节点的索引信息。
-
特点:
- 插入操作可能会触发节点分裂,以保持B+Tree的平衡性。
- 节点分裂会导致树的高度增加(在极端情况下),但B+Tree通过平衡操作来保持树的高度较低。
删除操作
-
过程:
- 找到应删除关键字所在的叶子节点。
- 从叶子节点中删除该关键字。
- 如果删除后叶子节点中的关键字数量少于最小容量,则进行节点合并或借用操作,以保持B+Tree的平衡性。
-
特点:
- 删除操作可能会触发节点合并或借用操作,以保持B+Tree的平衡性。
- 节点合并和借用操作可能会涉及多个节点和层级的调整。
优势与应用
-
优势:
- B+Tree具有更高的查询效率,因为所有叶子节点都在同一层,减少了查找过程中的磁盘I/O操作。
- B+Tree的范围查询和顺序遍历更加高效,因为叶子节点之间形成了有序链表结构。
-
应用:
- B+Tree广泛应用于数据库索引和文件系统等领域。
- 在数据库索引中,B+Tree用于加速数据检索和范围查询。
综上所述,B+Tree的原理基于其特殊的数据结构和高效的查找、插入、删除操作。这些特点使得B+Tree成为数据库索引和文件系统等领域的理想选择。
B+Tree与B-Tree的区别
B+Tree是B-Tree的一种变种,主要区别在于数据存储方式。在B+Tree中,所有的数据值都存储在叶子节点上,而内部节点只存储关键字信息。这种结构使得B+Tree在进行范围查询时更加高效。B+Tree的叶子节点通过指针相互连接,形成一个链表结构。这使得范围查询能够通过一次遍历叶子节点链表完成,避免了在B-Tree中可能出现的多次遍历操作。
综上所述,B-Tree是一种高效的数据结构,通过保持树的平衡性和有序性,支持高效的查找、插入和删除操作。它在数据库、文件系统和外部排序等领域具有广泛的应用前景。
相关文章:
数据结构(AVL树、B-Tree、B+Tree)
AVL树 AVL树是一种自平衡的二叉搜索树,它的特点是每个节点的左子树和右子树的高度差(平衡因子)的绝对值不超过1。这种平衡性保证了AVL树在进行查找、插入和删除操作时都能保持较高的效率。 平衡因子 在AVL树中,每个节点都维护一…...
可靠度的HLRF算法
一次可靠度的HLRF算法。随机向量的概率模型采用Nataf分布,考虑变量相关性。验算点搜寻采用U空间的梯度迭代算法。 资源文件列表 HLRF_method/HLRF_method.m , 4248 HLRF_method/Sample.m , 300 HLRF_method/Sample2.m , 335 HLRF_method/说明.txt , 659...
C++基础(2)
目录 1. 引用 1.1 引用的概念和定义 1.2 引用的特性 1.3 引用的使用 2. 常引用 3. 指针和引用的关系 4. 内联函数inline 5. nullptr 1. 引用 1.1 引用的概念和定义 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开…...
《海丰县蔡氏简介》--海丰县蔡姓宗支源流及始迁祖概述--海丰县各乡镇简介
《海丰县蔡氏简介》 三、海丰县蔡姓宗支源流及始迁祖概述 (一)海丰县各乡镇简介 排名不分先后 蔡惠进主编 海丰附城镇鹿境乡 始迁祖道山公(谥肇成),原籍福建箭田县猪菜街(御史街)八角井&…...
electron typescript运行并设置eslint检测
目录 一、初始化package.json 二、安装依赖 三、项目结构 四、配置启动项 五、补充:ts转js别名问题 已整理好的开源代码:Type-Electron: 用typescript开发的electron项目脚手架,轻量级、支持一键配置网页转PC - Gitee.com 一、初始化pac…...
modbus协议处理
//------------------------0x01-------------------------------- //MDA_usart_send: aa 55 01 00 06 00 02 00 05 //转modbusTCP——Master——send:地址00002,寄存器数量:00005 00 00 00 00 00 06 01 01 00 02 00 05 //ModbusTCP——Slave…...
Java Stream实战_函数式编程的新方式
1. 引言 1.1 Java Stream简介 Stream是什么:Stream是Java 8引入的一个接口,用于处理集合数据。与传统集合的区别:Stream不存储数据,而是通过管道操作(如过滤、映射)来处理数据。主要特点:惰性求值、链式调用、函数式编程风格。1.2 函数式编程基础 什么是函数式编程:一…...
java-(Oracle)-Oracle,plsqldev,Sql语法,Oracle函数
卸载好注册表,然后安装11g 每次在执行orderby的时候相当于是做了全排序,思考全排序的效率 会比较耗费系统的资源,因此选择在业务不太繁忙的时候进行 --给表添加注释 comment on table emp is 雇员表 --给列添加注释; comment on column emp.empno is 雇员工号;select empno,en…...
c++可变参数详解
目录 引言 库的基本功能 va_start 宏: va_arg 宏 va_end 宏 va_copy 宏 使用 处理可变参数代码 C11可变参数模板 基本概念 sizeof... 运算符 包扩展 引言 在C编程中,处理不确定数量的参数是一个常见的需求。为了支持这种需求,C标准库提供了 &…...
linux 函数 sem_init () 信号量、sem_destroy()
(1) (2) 代码举例: #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #include <unistd.h>sem_t semaphore;void* thread_function(void* arg) …...
基于python的体育新闻数据可视化及分析
项目 :北京冬奥会体育新闻数据可视化及分析 摘 要 随着社会的不断进步与发展,新时代下的网络媒体获取的信息也更加庞大和繁杂,相比于传统信息来源更加难以分析和辨别,造成了新时代媒体从业者撰写新闻的难度。在此背景下ÿ…...
CSS 基础:层叠、优先级与继承
CSS 基础:层叠、优先级与继承 一、层叠(Cascade)示例:层叠的顺序 二、优先级(Specificity)优先级规则示例:优先级的比较 三、继承(Inheritance)哪些属性会被继承…...
代码随想录算法【Day36】
Day36 1049. 最后一块石头的重量 II 思路 把石头尽可能分成两堆,这两堆重量如果相似,相撞后所剩的值就是最小值 若石头的总质量为sum,可以将问题转化为0-1背包问题,即给一个容量为sum/2的容器,如何尽量去凑满这个容…...
CNN的各种知识点(四): 非极大值抑制(Non-Maximum Suppression, NMS)
非极大值抑制(Non-Maximum Suppression, NMS) 1. 非极大值抑制(Non-Maximum Suppression, NMS)概念:算法步骤:具体例子:PyTorch实现: 总结: 1. 非极大值抑制(…...
为什么会有函数调用参数带标签的写法?Swift函数调用的参数传递需要加前缀是否是冗余?函数调用?函数参数?
为什么会有函数调用参数带标签的写法? ObjC函数参数形式与众不同,实参前会加前缀,尤其参数很多的情况,可读性很强。例如: [person setAge: 29 setSex:1 setClass: 35]; 这种参数前面加前缀描述也被叫标签(Label). 注意࿰…...
如可安装部署haproxy+keeyalived高可用集群
第一步,环境准备 服务 IP 描述 Keepalived vip Haproxy 负载均衡 主服务器 Rip:192..168.244.101 Vip:192.168.244.100 Keepalive主节点 Keepalive作为高可用 Haproxy作为4 或7层负载均衡 Keepalived vip Haproxy 负载均衡 备用服务…...
如何运行Composer安装PHP包 安装JWT库
1. 使用Composer Composer是PHP的依赖管理工具,它允许你轻松地安装和管理PHP包。对于JWT,你可以使用firebase/php-jwt这个库,这是由Firebase提供的官方库。 安装Composer(如果你还没有安装的话): 访问Co…...
安全策略配置
1.拓扑信息 2. 实验需求 3.需求分析 1.需要在交换机LSW1配置分配vlan并且为配置通道 2/3/4/5 在web界面或者命令行制定相应的安全策略 由于存在默认的拒绝需求4中生产区在任何时刻访问不了web不允许单独配置,只配置动作为运行的策略 4.配置信息 先配置服务器 …...
使用Chainlit快速构建一个对话式人工智能应用体验DeepSeek-R1
Chainlit是一个开源的 Python 包,用于构建可用于生产的对话式人工智能。 DeepSeek-R1 是一款强化学习(RL)驱动的推理模型,解决了模型中的重复性和可读性问题。在 RL 之前,DeepSeek-R1 引入了冷启动数据,进…...
Cursor 与多语言开发:全栈开发的利器
引言 全栈开发要求开发者跨越前端、后端、数据库甚至数据科学等多个技术领域,而不同技术栈往往需要切换工具和思维方式。Cursor 作为一款 AI 驱动的智能编程助手,凭借其对 20 编程语言 和主流框架的深度支持,正在成为全栈开发的“瑞士军刀”…...
生成式AI安全最佳实践 - 抵御OWASP Top 10攻击 (下)
今天小李哥将开启全新的技术分享系列,为大家介绍生成式AI的安全解决方案设计方法和最佳实践。近年来生成式 AI 安全市场正迅速发展。据IDC预测,到2025年全球 AI 安全解决方案市场规模将突破200亿美元,年复合增长率超过30%,而Gartn…...
家政预约小程序12服务详情
目录 1 修改数据源2 创建页面3 搭建轮播图4 搭建基本信息5 显示服务规格6 搭建服务描述7 设置过滤条件总结 我们已经在首页、分类页面显示了服务的列表信息,当点击服务的内容时候需要显示服务的详情信息,本篇介绍一下详情页功能的搭建。 1 修改数据源 在…...
知识蒸馏教程 Knowledge Distillation Tutorial
来自于:Knowledge Distillation Tutorial 将大模型蒸馏为小模型,可以节省计算资源,加快推理过程,更高效的运行。 使用CIFAR-10数据集 import torch import torch.nn as nn import torch.optim as optim import torchvision.tran…...
【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.29 NumPy+Scikit-learn(sklearn):机器学习基石揭秘
2.29 NumPyScikit-learn:机器学习基石揭秘 目录 #mermaid-svg-46l4lBcsNWrqVkRd {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-46l4lBcsNWrqVkRd .error-icon{fill:#552222;}#mermaid-svg-46l4lBcsNWr…...
DeepSeek-R1:通过强化学习提升大型语言模型推理能力的探索
DeepSeek-R1:通过强化学习提升大型语言模型推理能力的探索 在人工智能领域,大型语言模型(LLMs)的发展日新月异,其在自然语言处理和生成任务中的表现逐渐接近人类水平。然而,如何进一步提升这些模型的推理能…...
【C语言】指针详解:概念、类型与解引用
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 💯前言💯指针的基本概念1. 什么是指针2. 指针的基本操作 💯指针的类型1. 指针的大小2. 指针类型与所指向的数据类型3. 指针类型与数据访问的关系4. 指针类型的实际意…...
【怎么用系列】短视频戒断——对推荐算法进行干扰
如今推荐算法已经渗透到人们生活的方方面面,尤其是抖音等短视频核心就是推荐算法。 【短视频的危害】 1> 会让人变笨,慢慢让人丧失注意力与专注力 2> 让人丧失阅读长文的能力 3> 让人沉浸在一个又一个快感与嗨点当中。当我们刷短视频时&#x…...
【OS】AUTOSAR架构下的Interrupt详解(上篇)
目录 前言 正文 1.中断概念分析 1.1 中断处理API 1.2 中断级别 1.3 中断向量表 1.4 二类中断的嵌套 1.4.1概述 1.4.2激活 1.5一类中断 1.5.1一类中断的实现 1.5.2一类中断的嵌套 1.5.3在StartOS之前的1类ISR 1.5.4使用1类中断时的注意事项 1.6中断源的初始化 1.…...
UE编辑器工具
如何自己制作UE小工具提高工作效率 在虚幻编辑器用户界面中,可以使用各种各样的可视化工具来设置项目,设计和构建关卡,创建游戏性交互等等。但有些时候,当你确定了需要编辑器执行的操作后,可能想要通过编程方式调用它…...
【Linux】25.进程信号(2)
文章目录 4.捕捉信号4.1 重谈地址空间4.2 内核如何实现信号的捕捉4.3 sigaction4.4 可重入函数4.5 volatile4.6 SIGCHLD信号(了解) 4.捕捉信号 4.1 重谈地址空间 用户页表有几份? 有几个进程,就有几份用户级页表–进程具有独立性…...
