数据结构(AVL树、B-Tree、B+Tree)

news2025/2/5 15:38:49

AVL树

AVL树是一种自平衡的二叉搜索树,它的特点是每个节点的左子树和右子树的高度差(平衡因子)的绝对值不超过1。这种平衡性保证了AVL树在进行查找、插入和删除操作时都能保持较高的效率。

平衡因子

在AVL树中,每个节点都维护一个额外的信息,即平衡因子。平衡因子定义为该节点的左子树高度减去右子树高度(或右子树高度减去左子树高度,但通常以前者为准)。平衡因子的值只能为-1、0或+1。

旋转操作

当在AVL树上进行插入或删除操作时,可能会导致某些节点的平衡因子超出允许的范围(即绝对值大于1)。为了恢复平衡,AVL树采用旋转操作来调整节点的位置。旋转操作包括单旋转和双旋转两种类型:

  1. 单旋转
    • 右旋(LL旋转):当某个节点的左子节点的左子树上插入新节点,导致该节点的平衡因子变为+2时,进行右旋转操作。右旋转以该节点为根的子树,将其左子节点提升为新的根节点,该节点则成为新根节点的右子节点。
    • 左旋(RR旋转):与右旋类似,但方向相反。当某个节点的右子节点的右子树上插入新节点,导致该节点的平衡因子变为-2时,进行左旋操作。
  2. 双旋转
    • 先左后右旋转(LR旋转):当某个节点的左子节点的右子树上插入新节点,导致该节点的平衡因子变为+2,且其左子节点的平衡因子为+1时,先进行左旋操作调整左子树,再对根节点进行右旋操作。
    • 先右后左旋转(RL旋转):与LR旋转类似,但方向相反。当某个节点的右子节点的左子树上插入新节点,导致该节点的平衡因子变为-2,且其右子节点的平衡因子为-1时,先进行右旋操作调整右子树,再对根节点进行左旋操作。

AVL树操作

  1. 插入操作
    • 将新节点按照二叉搜索树的规则插入到AVL树中。
    • 从插入点开始,向上回溯到根节点,检查每个节点的平衡因子。
    • 若某节点的平衡因子超出范围,则根据具体情况进行旋转操作以恢复平衡。
  2. 删除操作
    • 找到要删除的节点,并将其向下旋转成一个叶子节点(若该节点不是叶子节点)。
    • 直接删除该叶子节点。
    • 从删除点开始,向上回溯到根节点,检查每个节点的平衡因子。
    • 若某节点的平衡因子超出范围,则根据具体情况进行旋转操作以恢复平衡。
  3. 查找操作
    • AVL树的查找操作与二叉搜索树相同,利用平衡性保证查找效率为O(log n)。

AVL树的优势与应用

AVL树的优势在于其严格的平衡性保证了所有基本操作(查找、插入、删除)的时间复杂度均为O(log n)。这使得AVL树在需要频繁进行这些操作的场景中表现出色,如数据库索引、内存管理等。然而,AVL树在插入和删除操作时需要频繁进行旋转操作以维持平衡性,这可能会增加一些额外的开销。尽管如此,AVL树仍然是一种高效且广泛应用的自平衡二叉搜索树。

B-Tree

B-Tree(Balanced Tree),即B树,是一种自平衡的树形数据结构,专为磁盘和其他直接访问的辅助存储设备而设计,广泛应用于数据库和文件系统中。以下是B-Tree原理的详细解释:

基本概念

  1. 多路搜索树:B树是一种多路搜索树,也被称为平衡多路查找树。与二叉搜索树不同,B树的每个节点可以拥有多个子节点和键值。
  2. 键值:节点中的键值按照升序排列,并作为子树的分隔键。
  3. 子节点指针:每个键值将节点分割成多个子树,每个子树由一个子节点指针指向。
  4. 叶子节点:叶子节点不包含键值对应的记录,但通常包含指向实际记录的指针。
  5. 阶(Order)或分支因子(Branch Factor):通常用字母m表示,它定义了节点可以拥有的最大子节点数(即m个子节点)。因此,一个节点最多可以有m-1个键值。非根节点至少需要有⌈m/2⌉个子节点,以保持树的平衡。

性质

  1. 高度平衡:B树是一种高度平衡的数据结构,所有叶子节点都位于同一层。这种平衡性确保了所有查找、插入和删除操作的时间复杂度都是O(log n),其中n是树中元素的数量。
  2. 有序性:节点中的键值按照从小到大的顺序排列,这有助于在查找过程中快速定位目标数据。

操作

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

应用

  1. 数据库索引:B树通过减少磁盘访问次数,显著提高了数据库查询的效率。在数据库中,索引是帮助快速查找数据的数据结构。B树作为索引结构,能够支持高效的查找、插入和删除操作。
  2. 文件系统:B树也常用于文件系统中,用于快速定位文件的存储位置。通过B树,文件系统可以高效地管理元数据(如文件名、文件大小、创建时间等),并快速访问文件数据。
  3. 外部排序:在外部排序中,由于数据量太大,无法一次性装入内存,因此需要使用磁盘等外部存储设备。B树可以作为外部排序过程中的一个关键数据结构,帮助实现多路归并排序,提高排序的效率。

B+Tree

B+Tree的原理主要基于其数据结构和查找、插入、删除等操作的特点。以下是对B+Tree原理的详细解释:

数据结构

B+Tree是B树(Balanced Tree)的一种变形,是一种多路平衡查找树。在B+Tree中,数据被存储在叶子节点,而非叶子节点仅用于索引,不存储实际数据。这种结构使得B+Tree在查找、插入和删除操作时具有更高的效率。

  1. 节点类型

    • 根节点:B+Tree的起始节点,用于引导查找过程。
    • 内部节点(非叶子节点):仅包含索引信息和指向子节点的指针,不存储实际数据。
    • 叶子节点:存储实际数据和指向下一个叶子节点的指针,形成有序链表结构。
  2. 节点结构

    • 每个节点包含一定数量的关键字(key)和指针(pointer)。
    • 关键字按升序排列,指针指向包含相应关键字的子节点或叶子节点。
  3. 节点容量

    • 每个节点有一个最大容量,当节点中的关键字数量达到最大容量时,会发生节点分裂。

查找操作

  1. 过程

    • 从根节点开始,根据关键字进行二分查找。
    • 找到匹配的关键字所在的指针,递归地进入子节点进行查找。
    • 最终到达叶子节点,在叶子节点上进行二分查找或顺序遍历找到目标数据。
  2. 特点

    • B+Tree的查找过程稳定且高效,因为所有叶子节点都在同一层,树的高度较低。
    • 叶子节点之间的有序链表结构使得范围查询和顺序遍历更加高效。

插入操作

  1. 过程

    • 找到应插入叶子节点的位置。
    • 将新关键字插入叶子节点。
    • 如果叶子节点已满,则进行节点分裂,将部分关键字和指针移动到新的节点,并更新父节点的索引信息。
  2. 特点

    • 插入操作可能会触发节点分裂,以保持B+Tree的平衡性。
    • 节点分裂会导致树的高度增加(在极端情况下),但B+Tree通过平衡操作来保持树的高度较低。

删除操作

  1. 过程

    • 找到应删除关键字所在的叶子节点。
    • 从叶子节点中删除该关键字。
    • 如果删除后叶子节点中的关键字数量少于最小容量,则进行节点合并或借用操作,以保持B+Tree的平衡性。
  2. 特点

    • 删除操作可能会触发节点合并或借用操作,以保持B+Tree的平衡性。
    • 节点合并和借用操作可能会涉及多个节点和层级的调整。

优势与应用

  1. 优势

    • B+Tree具有更高的查询效率,因为所有叶子节点都在同一层,减少了查找过程中的磁盘I/O操作。
    • B+Tree的范围查询和顺序遍历更加高效,因为叶子节点之间形成了有序链表结构。
  2. 应用

    • 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是一种高效的数据结构,通过保持树的平衡性和有序性,支持高效的查找、插入和删除操作。它在数据库、文件系统和外部排序等领域具有广泛的应用前景。

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

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

相关文章

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-(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()

&#xff08;1&#xff09; &#xff08;2&#xff09; 代码举例&#xff1a; #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #include <unistd.h>sem_t semaphore;void* thread_function(void* arg) …

基于python的体育新闻数据可视化及分析

项目 &#xff1a;北京冬奥会体育新闻数据可视化及分析 摘 要 随着社会的不断进步与发展&#xff0c;新时代下的网络媒体获取的信息也更加庞大和繁杂&#xff0c;相比于传统信息来源更加难以分析和辨别&#xff0c;造成了新时代媒体从业者撰写新闻的难度。在此背景下&#xff…

代码随想录算法【Day36】

Day36 1049. 最后一块石头的重量 II 思路 把石头尽可能分成两堆&#xff0c;这两堆重量如果相似&#xff0c;相撞后所剩的值就是最小值 若石头的总质量为sum&#xff0c;可以将问题转化为0-1背包问题&#xff0c;即给一个容量为sum/2的容器&#xff0c;如何尽量去凑满这个容…

如可安装部署haproxy+keeyalived高可用集群

第一步&#xff0c;环境准备 服务 IP 描述 Keepalived vip Haproxy 负载均衡 主服务器 Rip&#xff1a;192..168.244.101 Vip&#xff1a;192.168.244.100 Keepalive主节点 Keepalive作为高可用 Haproxy作为4 或7层负载均衡 Keepalived vip Haproxy 负载均衡 备用服务…

如何运行Composer安装PHP包 安装JWT库

1. 使用Composer Composer是PHP的依赖管理工具&#xff0c;它允许你轻松地安装和管理PHP包。对于JWT&#xff0c;你可以使用firebase/php-jwt这个库&#xff0c;这是由Firebase提供的官方库。 安装Composer&#xff08;如果你还没有安装的话&#xff09;&#xff1a; 访问Co…

安全策略配置

1.拓扑信息 2. 实验需求 3.需求分析 1.需要在交换机LSW1配置分配vlan并且为配置通道 2/3/4/5 在web界面或者命令行制定相应的安全策略 由于存在默认的拒绝需求4中生产区在任何时刻访问不了web不允许单独配置&#xff0c;只配置动作为运行的策略 4.配置信息 先配置服务器 …

使用Chainlit快速构建一个对话式人工智能应用体验DeepSeek-R1

Chainlit是一个开源的 Python 包&#xff0c;用于构建可用于生产的对话式人工智能。 DeepSeek-R1 是一款强化学习&#xff08;RL&#xff09;驱动的推理模型&#xff0c;解决了模型中的重复性和可读性问题。在 RL 之前&#xff0c;DeepSeek-R1 引入了冷启动数据&#xff0c;进…

生成式AI安全最佳实践 - 抵御OWASP Top 10攻击 (下)

今天小李哥将开启全新的技术分享系列&#xff0c;为大家介绍生成式AI的安全解决方案设计方法和最佳实践。近年来生成式 AI 安全市场正迅速发展。据IDC预测&#xff0c;到2025年全球 AI 安全解决方案市场规模将突破200亿美元&#xff0c;年复合增长率超过30%&#xff0c;而Gartn…

家政预约小程序12服务详情

目录 1 修改数据源2 创建页面3 搭建轮播图4 搭建基本信息5 显示服务规格6 搭建服务描述7 设置过滤条件总结 我们已经在首页、分类页面显示了服务的列表信息&#xff0c;当点击服务的内容时候需要显示服务的详情信息&#xff0c;本篇介绍一下详情页功能的搭建。 1 修改数据源 在…

知识蒸馏教程 Knowledge Distillation Tutorial

来自于&#xff1a;Knowledge Distillation Tutorial 将大模型蒸馏为小模型&#xff0c;可以节省计算资源&#xff0c;加快推理过程&#xff0c;更高效的运行。 使用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&#xff1a;机器学习基石揭秘 目录 #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…

【C语言】指针详解:概念、类型与解引用

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 &#x1f4af;前言&#x1f4af;指针的基本概念1. 什么是指针2. 指针的基本操作 &#x1f4af;指针的类型1. 指针的大小2. 指针类型与所指向的数据类型3. 指针类型与数据访问的关系4. 指针类型的实际意…

【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小工具提高工作效率 在虚幻编辑器用户界面中&#xff0c;可以使用各种各样的可视化工具来设置项目&#xff0c;设计和构建关卡&#xff0c;创建游戏性交互等等。但有些时候&#xff0c;当你确定了需要编辑器执行的操作后&#xff0c;可能想要通过编程方式调用它…

【Linux】25.进程信号(2)

文章目录 4.捕捉信号4.1 重谈地址空间4.2 内核如何实现信号的捕捉4.3 sigaction4.4 可重入函数4.5 volatile4.6 SIGCHLD信号&#xff08;了解&#xff09; 4.捕捉信号 4.1 重谈地址空间 用户页表有几份&#xff1f; 有几个进程&#xff0c;就有几份用户级页表–进程具有独立性…