数据库-数据结构

数据库-数据结构

  • 一、B-树、B+树、B*树
    • 1 B-树
    • 2 B+树
    • 3 B*树
  • 二、AVL树
    • 1 左旋
    • 2 右旋
    • 3 LL
    • 4 RR
    • 5 LR
    • 6 RL
  • 三、红黑树
    • 1 插入操作
      • 1.1 父节点是黑色
      • 1.2 父节点是红色且叔父节点是红色
      • 1.3 父节点是红色且叔父节点是黑色
    • 2 删除操作
      • 2.1 有2个孩子
      • 2.1 有1个孩子
      • 2.3 没有孩子
        • 2.3.1 节点为红色
        • 2.3.2 父节点为红色,兄弟节点无孩子
        • 2.3.3 父节点为红色,兄弟节点有孩子
        • 2.3.4 节点为黑色,父节点为黑色,兄弟节点有左孩子
        • 2.3.5 节点为黑色,父节点为黑色,兄弟节点只有右孩子
        • 2.3.6 节点为黑色,父节点为黑色,兄弟节点无孩子

一、B-树、B+树、B*树

搜索树:左子节点<节点<右子节点。
B-树:多路搜索树。
B+树:B-树的变体,更适用于文件系统,如mysql数据库。具体的,适合通过叶子节点的链指针进行区间查找。
B*树:B+树变体,提高了空间使用率 1 / 2 → 2 / 3 1/2→2/3 1/22/3
参考文章:一文详解 B-树,B+树,B*树

1 B-树

在这里插入图片描述

对于一颗m阶B-树(上图m=3)
特点:

  1. 根节点至少有2个子节点,或者为空树。
  2. 非叶子节点的子节点数k: ⌈ m / 2 ⌉ ≤ k ≤ m \lceil m/2\rceil ≤k≤m m/2km。当一个节点满了,分配一个新节点,把原节点一半的数据移动到新节点,并将该新节点加入到父节点中。此时改动只有该满的节点和其父节点。
  3. 非叶子节点的关键字数j: j = k − 1 j=k-1 j=k1
  4. 叶子节点在同一层。
  5. 对于某个节点的关键字K[1],K[2]…K[M-1],K[i]<K[i+1]。
  6. 对于某个非叶子节点的指针P[1],P[2]…P[M],P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其他的P[i]指向关键字在范围(K[i],K[i+1])的子树。
  7. 关键字分布在整棵树。
  8. 搜索过程中可能在非叶子节点结束。时间复杂度等于一次二分查找。

2 B+树

在这里插入图片描述
对于一颗m阶B+树(上图m=3)
与B-树的不同:

  1. 应文件系统所需的B-树变体。
  2. 非叶子节点的关键字个数j: j = k j=k j=k
  3. 关键字不保存数据,仅用于索引。数据保存在叶子节点。
  4. 对于某个非叶子节点的指针P[1],P[2]…P[M],P[i]指向关键字在范围[K[i],K[i+1])的子树。
  5. 所有叶子节点由一个链指针链接起来。
  6. 关键字分布在叶子节点。
  7. 搜索过程中得到叶子节点才结束。时间复杂度仍然等于一次二分查找。

3 B*树

在这里插入图片描述

对于一颗m阶B*树(上图m=3)
与B+树的不同:

  1. 在非根非叶子节点的层增加了兄弟指针。
  2. 非叶子节点的子节点数k: ⌈ 2 m / 3 ⌉ ≤ k ≤ m \lceil 2m/3\rceil ≤k≤m 2m/3km,原先是 ⌈ m / 2 ⌉ ≤ k ≤ m \lceil m/2\rceil ≤k≤m m/2km,提高了块的最低使用率。当一个节点满了,根据兄弟指针检查兄弟节点是否满了,未满则将一部分数据移动到兄弟节点;如果满了则分配一个新节点,把原节点和兄弟节点各自 1 / 3 1/3 1/3的数据移动到新节点,并将该新节点加入到父节点中。此时改动有该满的节点、其父节点、兄弟节点、兄弟指针。

二、AVL树

搜索树:左子节点<节点<右子节点。有些有序的数据搭建成二叉搜索树后,可能会退化成了一个链表。AVL树通过控制平衡因子在[-1,1]内来避免退化。
AVL树:平衡二叉搜索树。即左右子树的高度差小于等于1,并且其子树也是平衡二叉树。
平衡因子:节点的左子树高度 - 节点的右子树高度。用于判断节点的平衡状态。
影响平衡因子的操作:删除节点、添加节点。
2种基础的平衡化操作:左旋、右旋。
4种需要平衡操作的情况:LL、RR、LR、RL。

需要平衡的情况状态操作
LL平衡因子为2,左子树平衡因子为1右旋
RR平衡因子为-2,右子树平衡因子为-1左旋
LR平衡因子为2,左子树平衡因子为-1对左子树左旋、再对该节点右旋
RL平衡因子为-2,右子树平衡因子为1对右子树右旋、再对该节点左旋

参考文章:详解 AVL 树(基础篇)

1 左旋

在这里插入图片描述
逆时针旋转,如果节点B有左子树。则将B的左子树作为A的右子树。

2 右旋

在这里插入图片描述
顺时针旋转,如果节点B有右子树。则将B的右子树作为C的左子树。

3 LL

在这里插入图片描述
状态:节点n的平衡因子为2,左节点i的平衡因子为1。
平衡操作:对节点n进行一次右旋操作。

4 RR

状态和操作与LL对称。

5 LR

在这里插入图片描述
状态:节点n的平衡因子为2,左节点i的平衡因子为-1。
平衡操作:1先对节点i进行一次左旋操作,2再对节点n进行一次右旋操作。

6 RL

状态和操作与LR对称。

三、红黑树

搜索树:左子节点<节点<右子节点。有些有序的数据搭建成二叉搜索树后,可能会退化成了一个链表,时间复杂度最高是O(n)。AVL树通过控制平衡因子在[-1,1]内来避免退化,使得其查找的时间复杂度是O(logn),但是增删节点时的平衡成本很高,所以出现了红黑树。

红黑树:自平衡二叉搜索树。
叶子节点:null节点,即叶子节点没有数据。所以下图中那些没有子节点的非null节点,默认是有2个null的叶子节点。
参考文章:最通俗易懂入门红黑树(R-B Tree)、
图解红黑树的插入及调整过程+源码解读、 红黑树(二):删除操作
红黑树特点:

  1. 节点颜色有黑色、红色2种。
  2. 根节点为黑色。
  3. 叶子节点为黑色。
  4. 父子节点不能同时为红色。
  5. 从一个节点出发,到它的任意一个叶子节点,经过的黑色节点数相同。
    在这里插入图片描述

上述特点得出的一些推论:

  1. 根据特点4和5,从一个节点出发,到它的叶子节点的最长路径长度不会超过最短路径的2倍。此时最长路径是红黑间隔的,最短路径是全黑的。
  2. 根据特点5,新插入的节点为红色节点。此时,不会破坏特点5但有可能破坏特点4,需要做一些变色和旋转的操作。

1 插入操作

红黑树也是二叉搜索树,当有新的节点时,根据最小右大的规则先找到它的插入位置(即它的父节点以及它是左孩子还是右孩子),然后标记为红色,最后根据红黑树的特点,进行变色和旋转。
变色和旋转的判断规则:

情况变色旋转
父节点是黑色
父节点是红色且叔父节点是红色
父节点是红色且叔父节点是黑色

1.1 父节点是黑色

在这里插入图片描述
例如上图,插入66,此时仍然满足红黑树的特点。

1.2 父节点是红色且叔父节点是红色

在这里插入图片描述
例如上图,插入51。此时,49和51都是红色,所以不满足特点4,需要进行变色。
第一步,应该就是将父节点49和叔父节点43变成黑色,以满足特点4;
第二步,将祖父节点45变成红色,使得更上层的节点满足特点5。
第三步,此时递归到祖父节点,判断其是否出现违反特点4的情况,有则重复第一步和第二步,没有则执行第4步。
第四步:如果根节点变成了红色,重新染黑。

步骤图:
在这里插入图片描述
最终结果图:
在这里插入图片描述

1.3 父节点是红色且叔父节点是黑色

在这里插入图片描述

如果插入65,则其会成为66的左孩子。此时,叔父节点null是黑色,导致父节点66变成黑色后,该分支的路径比叔父节点的路径多了1个黑色,不满足特点5,所以需要进行旋转。其实旋转的目的和AVL树一样,插入节点后导致出现平衡因子=2或-2的情况,需要平衡。
在这里插入图片描述
不平衡情况有LL、RR、LR、RL四种,在AVL树中有说明。对于红黑树,旋转(LR和RL需要先旋转变为LL和RR)-变色-旋转。
LL:插入65。先变色,然后对祖父节点69进行右旋。
在这里插入图片描述

RR:插入70。先变色,然后对祖父节点66进行左旋。
在这里插入图片描述
LR:插入67。先对父节点左旋变成LL,然后根据LL的操作先变色再对祖父节点69右旋。
在这里插入图片描述
RL:插入68。先对父节点右旋变成RR,然后根据RR的操作先变色再对祖父节点66右旋。
在这里插入图片描述

2 删除操作

删除比插入要考虑更多因素。首先,删除可能删的是中间层的节点,其次,删除的节点可能是黑色。
按照删除的位置,有3种情况,有2个孩子、有1个孩子、没有孩子。

情况处理方式是否按颜色分类处理
有2个孩子先根据中序遍历找到后继节点(右子树中最小的节点),然后替换掉。此时情况转变为(有1个孩子、没有孩子),按照这2种情况处理。看后继节点是否有孩子
有1个孩子直接删除,然后让父节点指向子节点,子节点变色
没有孩子根据节点(当前节点、父节点、兄弟节点)颜色分情况处理

2.1 有2个孩子

在这里插入图片描述
如果要删除节点-1,则先跟后继节点0替换,问题转化为删除0(没有孩子),需要考虑节点颜色进行处理。
如果要删除节点4,则先跟后继节点5替换,问题转化为删除5(有1个孩子),不需要考虑节点颜色。

2.1 有1个孩子

在这里插入图片描述
删除节点D
颜色判断:D一定是黑色,孩子一定是红色
反证:如果该孩子是黑色,那么节点D的2个分支路径黑色节点数不相等(1≠2),不满足特点5。所以孩子是红色,再根据特点4,D是黑色。
操作:删除D,然后将子节点变黑色并作为父节点的新子节点。

2.3 没有孩子

需要根据节点颜色,分6种情况。
由于对称的情况操作是类似的,所以这里后3种情况都是以删除节点是其父亲节点的左子节点来讨论。

2.3.1 节点为红色

在这里插入图片描述
删除节点D
颜色判断:根据特点4,父节点必然是黑色。
操作:直接删除即可,不影响特点5。

2.3.2 父节点为红色,兄弟节点无孩子

在这里插入图片描述
删除节点D
颜色判断:根据特点4,当前节点和其兄弟节点为黑色。
操作:先删除节点;然后将父节点变成黑色;最后将兄弟节点变成红色。

2.3.3 父节点为红色,兄弟节点有孩子

在这里插入图片描述
删除节点D
颜色判断:兄弟节点的孩子为红色,否则父节点的左右分支不满足特点5。
操作:先删除节点D;然后判断父节点P是RL还是RR类型,如果是RL则右旋兄弟节点B得到RR类型;对父节点P、兄弟节点B和兄弟孩子节点BR进行变色(如果是RL转RR的不需要对BR变色);对父节点P左旋。

2.3.4 节点为黑色,父节点为黑色,兄弟节点有左孩子

在这里插入图片描述
删除节点B
颜色判断:兄弟节点的孩子为红色,否则父节点的左右分支不满足特点5。
操作:先删除节点B;此时父节点P是RL类型,需要进行右旋得到RR,并且对节点D和DL变色使得满足特点4;接着对节点P进行做左旋;最后对DL进行变色使得满足特点5。

2.3.5 节点为黑色,父节点为黑色,兄弟节点只有右孩子

在这里插入图片描述

删除节点B
颜色判断:同2.3.4。
操作:比2.3.4少一次右旋。先删除节点B;接着对节点P进行做左旋;最后对DR进行变色使得满足特点5。

2.3.6 节点为黑色,父节点为黑色,兄弟节点无孩子

在这里插入图片描述
删除节点B
操作:先删除节点B,然后将兄弟节点D染成黑色。此时,P这个分支满足特点4和5,但是P的更上层左右分支不满足特点5,所以需要向上递归。
递归过程:如果P的父节点是红色,则根据2.3.2和2.3.3来处理。如果是黑色,则根据2.3.4/2、2.3.5、2.3.6处理。(这里可能还得再细化一下,使得具体操作可以递归处理)

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

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

相关文章

DOM 的 diff 算法

经典面试题&#xff1a; 1&#xff09;react/vue中的 key 有什么作用&#xff1f;&#xff08;key的内部原理是什么&#xff1f;&#xff09; 2&#xff09;为什么遍历列表时&#xff0c;key 最好不用 index&#xff1f; 1、虚拟dom中key的作用&#xff1a; 1&#xff09; 简…

Python GUI库大汇总

所有程序都是基于命令行的&#xff0c;这些程序可能只有一些“专业”的计算机人士才会使用。例如前面编写的五子棋等程序&#xff0c;恐怕只有程序员自己才愿意玩这么“糟糕”的游戏&#xff0c;很少有最终用户愿意对着黑乎乎的命令行界面敲命令。 相反&#xff0c;如果为程序…

联想小新M7268一体机常用功能和操作步骤

联想小新M7268黑白激光多功能打印一体机&#xff0c;小身材、大智慧&#xff0c;小心M7268身材十分娇小&#xff0c;净尺寸方面为350*275*135mm&#xff08;长*宽*高&#xff09;&#xff08;手工测量&#xff09;&#xff0c;在实际使用时&#xff0c;小新M7268所占空间要略大…

Linux平台建立GB28181设备模拟器

目录 下载模拟器解决动态库缺少问题运行模拟器抓包参考资料 在没有GB28181摄像机的情况下,在Linux虚拟机中模拟出一台GB28181摄像机用于调试和学习. 下载模拟器 到网站下载Linux 平台版本: https://www.happytimesoft.com/download.html tar -zxvf happytime-gb28181-device…

使用 Docker 部署 Halo 博客系统

:::info 项目地址&#xff1a;https://github.com/halo-dev/halo ::: 一、Halo 介绍 1&#xff09;Halo 简介 Halo 是一款强大易用的开源建站工具&#xff0c;它让你无需太多的技术知识就可以快速搭建一个博客、网站或者内容管理系统。具备可插拔架构、主题套用、富文本编辑器…

基于Springboot的私人健身与教练预约管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的私人健身与教练预约管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三…

某侠网js逆向wasm解析

本次目标地址如下&#xff0c;使用base64解密获得 aHR0cHM6Ly93d3cud2FpbWFveGlhLm5ldC9sb2dpbg 打开网址&#xff0c;本次的目标是登录接口&#xff0c;如下图 本文主要讲解wasm的解析&#xff0c;所以对其他参数不做逆向处理&#xff0c;本次由wasm加密的参数只有sign一个&a…

分布式存储

1 存储基础 1.1 单机存储设备 DAS&#xff08;直接附加存储&#xff0c;是直接接到计算机打的主板总线上去的存储&#xff09; UDE、SATA、SCSI、SAS、USB接口的磁盘 所谓的接口就是一种存储设备驱动下的磁盘设备&#xff0c;提供块级别的存储 NAS&#xff08;网络附加存储…

BLHeli_S 代码分析---BLHeli.asm入口函数pgm_start分析

BLHeli_S 代码分析—BLHeli.asm入口函数pgm_start分析 pgm_start 代码 代码中数据变量定义 Bit_Access: DS 1Flash_Key_1: DS 1 ; Flash key one Flash_Key_2: DS 1 ; Flash key twoAIKON_Boltlite_30A.inc文件中定义的变量 LOCK_BYTE_ADDRESS_16K EQU 3FFFh ; Ad…

苹果最新系统iOS 17的调试和适配方法 - Xcode 14.3.1 真机调试指南

最近苹果发布了iOS 17作为其最新操作系统版本&#xff0c;作为开发者&#xff0c;你可能需要了解如何在Xcode 14.3.1中进行真机调试和适配。本文将为你详细介绍步骤和注意事项。 I. 检查Xcode版本 在开始之前&#xff0c;确保你已经安装了Xcode 14.3.1或更高版本。你可以在Xco…

APP广告变现设置合理的广告频次的原因

过多的广告展示可能会导致用户体验下降&#xff0c;而过少则可能会降低广告收入&#xff0c;我们需要的是找到其中的平衡点。 广告频次限制可以通过多种方式实现&#xff0c;比如限制某段时间内广告出现的次数、限制某个用户在一定时间内看到广告的次数等。在实践中&#xff0…

SpringBoot+SSM项目实战 苍穹外卖(12) Apache POI

继续上一节的内容&#xff0c;本节是苍穹外卖后端开发的最后一节&#xff0c;本节学习Apache POI&#xff0c;完成工作台、数据导出功能。 目录 工作台Apache POI入门案例 导出运营数据Excel报表 工作台 工作台是系统运营的数据看板&#xff0c;并提供快捷操作入口&#xff0c…

【目标检测实验系列】YOLOv5模型改进:融入坐标注意力机制CA,多维度关注数据特征,高效涨点!(内含源代码,超详细改进代码流程)

自我介绍&#xff1a;本人硕士期间全程放养&#xff0c;目前成果:一篇北大核心CSCD录用,两篇中科院三区已见刊&#xff0c;一篇中科院四区在投。如何找创新点&#xff0c;如何放养过程厚积薄发&#xff0c;如何写中英论文&#xff0c;找期刊等等。本人后续会以自己实战经验详细…

免费开源OCR 软件Umi-OCR

Umi-OCR 是一款免费、开源、可批量的离线 OCR 软件&#xff0c;基于 PaddleOCR&#xff0c;适用于 Windows10/11 平台 免费&#xff1a;本项目所有代码开源&#xff0c;完全免费。方便&#xff1a;解压即用&#xff0c;离线运行&#xff0c;无需网络。高效&#xff1a;自带高效…

07 整合SSM的快速理解

1.1 第一问&#xff1a;SSM整合需要几个IoC容器&#xff1f; 两个容器 本质上说&#xff0c;整合就是将三层架构和框架核心API组件交给SpringIoC容器管理&#xff01; 一个容器可能就够了&#xff0c;但是我们常见的操作是创建两个IoC容器&#xff08;web容器和root容器&…

C++ 设计模式之桥接模式

【声明】本题目来源于卡码网&#xff08;题目页面 (kamacoder.com)&#xff09; 【提示&#xff1a;如果不想看文字介绍&#xff0c;可以直接跳转到C编码部分】 【简介】什么是桥接模式 桥接模式&#xff08;Bridge Pattern&#xff09;是⼀种结构型设计模式&#xff0c;它的U…

不是人才用不起,而是AI巡检更有性价比!

在许多行业中&#xff0c;如煤炭、电力、化工等&#xff0c;安全生产是至关重要的。这就需要通过巡检&#xff0c;对设备运行状态进行实时监测&#xff0c;及时发现并处理潜在的安全隐患&#xff0c;从而降低事故发生的概率。但是传统的巡检方式通常依赖于人工进行&#xff0c;…

Java项目:121SSM记账管理系统

博主主页&#xff1a;Java旅途 简介&#xff1a;分享计算机知识、学习路线、系统源码及教程 文末获取源码 一、项目介绍 记账管理系统基于SpringSpringMVCMybatis开发&#xff0c;系统主要功能如下&#xff1a; 收入项管理 支出项管理 收入方式管理 支出方式管理 添加收入…

申泰勇教练的独家人物化身系列即将登陆 The Sandbox

申泰勇&#xff08;Shin Tae-yong&#xff09;教练是足球界的传奇人物&#xff0c;他来到 The Sandbox&#xff0c;推出了自己的专属人物化身系列。作为前 K 联赛中场球员和印尼队取得历史性成就的幕后教练&#xff0c;他的传奇经历现在已经影响到了虚拟世界。 向过去、现在和未…

Linux第29步_安装“Notepad++”软件

STM32CubeProgrammer脚本文件的后缀为“.tsv”&#xff0c;ST公司官方也叫做FlashLayout。在烧写“TF-A固件”之前&#xff0c;我们需要用“Notepad”软件打开“后缀为.tsv”的脚本文件&#xff0c;根据需求决定哪些文件需要更新&#xff0c;设置好这个脚本文件。 在后期使用S…
最新文章