11-看图理解数据结构与算法系列(B树的删除)
删除操作
删除操作比较复杂,主要是因为删除的项可能在叶子节点上也可能在非叶子节点上,而且删除后可能导致不符合B树的规定,这里暂且称之为导致B树不平衡,于是要进行一些合并、左旋、右旋等操作,使之符合B树的规定(即让B树平衡)。另外,如果是删除非叶子节点项需要先找到中序前驱来替换。
情况一
要删除的项在叶子节点上且不影响B树的平衡结构,比如删除“I”,从根节点开始查找,“I”大于“D”,往第二个分支,
逐一与节点内项的值进行比较,“I”大于“F”,继续比较,“I”大于“H”继续比较,“I”小于“K”,所以往第三个分支继续往下查找,
此时找到“I”,
直接删除“I”,完成删除操作。
情况二
要删除的项在叶子节点上,删除后打破平衡需要从右兄弟节点中借项,而且右兄弟节点有足够的项借给它。比如删除“G”,从根节点开始查找,“G”大于“D”,往右子树,
逐一比较节点内项的值,发现应该往第二个分支,
找到“G”,
此时发现“G”节点的右兄弟节点有项可以借给它,于是删除“G”,然后进行左旋操作,左旋即原来的父节点“H”下移到左子节点填补原来的“G”节点,右子节点中最小值的项“I”提升到父节点,最终如下,
完成删除操作。
情况三
要删除的项在叶子节点上,删除后打破平衡需要从左兄弟节点中借项,而且左兄弟节点有足够的项借给它。比如删除“L”,从根节点开始查找,“L”大于“D”,往右子树,
逐一比较节点内项的值,发现应该往第四个分支,
找到“L”,
此时发现“L”节点的左兄弟节点有项可以借给它,于是删除“L”,然后进行右旋,右旋即原来的父节点“K”下移到右子节点填补原来的“L”节点,左子节点中最大值的项“J”提升到父节点,最终如下,
完成删除操作。
情况四
要删除的项在叶子节点上,删除后打破平衡,而且左右兄弟节点都没有项可以借给它。比如删除“G”,从根节点开始查找,“G”大于“D”,往右子树,
逐一比较节点内项的值,发现应该往第二个分支,
找到“G”,
此时发现“G”节点删除掉后,左右兄弟节点都无法借项给它,执行合并操作,
合并操作主要是将父节点对应的项“F”下移到左子节点中,同时也将右子节点中剩余的项全部也移到左子节点中(注意这里右子节点删除“G”项后已无其他项),最终结果如下,完成删除操作。
需要注意的是如果执行合并操作后使父节点不平衡,则需要继续对父节点继续进行平衡处理。比如下面的例子,需要删除“C”项,从根节点开始于“D”比较,小于“D”则往往第一个分支,
逐一与子节点内的项比较,“C”大于“B”则往第二个分支,
找到“C”,
此时发现“C”项删除掉后,左右兄弟节点都无法借项给它,
执行合并操作,将父节点对应的项“B”下移到左子节点中,同时也将右子节点中剩余的项全部也移到左子节点中,合并后结果如下,父节点已经变成空了,树不平衡,
此时父节点的右兄弟节点可以借项给它,即执行左旋操作,父节点的父节点“D”下移到父节点,父节点的兄弟节点的最左边项“F”上升,
另外,左旋操作还包括要将移动项“F”对应节点的第一个分支(即“E”)移到父节点“D”的最右分支,最终结果如下,
情况五
要删除的项在非叶子节点上。比如删除“M”,从根节点开始查找,“M”大于“H”,往第二个分支,
逐一比较子节点内的项,找到“M”,
非叶子节点项的删除的第一步就是要先找到对应的中序前驱,即第一个分支子节点中最大值的项,
然后一直往最后一个分支找,最终找到“L”为前驱,将其提升到待删除项“M”的位置,导致了树不平衡,但它发现兄弟节点可以借项给它,
于是进行右旋操作,父节点“K”下移到原来前驱的位置,左兄弟节点最右边的项“J”提升到父节点,另外如果左兄弟节点“J”项有右子节点的话,也需要挂到“K”节点的左边。最终完成删除操作。
除此之外,再看看删除根节点的情况,删除只有一个项的根节点,比如删除“D”,
先找中序前驱,即第一个分支子节点中最大值的项,
一直往最后一个分支找,最终找到“C”为前驱,将其提升到根节点中,
此时引起不平衡,而且原来“C”节点的左右兄弟节点都无法借项给它,
此时只能做合并处理,将父节点的项“B”下移到左子节点,合并后原来的父节点变为空,产生了不平衡,此时它的兄弟节点可以借项给它,所以需要执行左旋操作,
左旋即将“C”下移,“F”提升,
而且还要将“E”项挂到“C”节点上,最终如下。
作者:超人汪小建
链接:https://juejin.im/post/5b95ba52f265da0af87952a9
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
11-看图理解数据结构与算法系列(B树的删除)的更多相关文章
- 06-看图理解数据结构与算法系列(AVL树)
AVL树 AVL树,也称平衡二叉搜索树,AVL是其发明者姓名简写.AVL树属于树的一种,而且它也是一棵二叉搜索树,不同的是他通过一定机制能保证二叉搜索树的平衡,平衡的二叉搜索树的查询效率更高. AVL ...
- 09-看图理解数据结构与算法系列(B树)
B树 B树即平衡查找树,一般理解为平衡多路查找树,也称为B-树.B_树.是一种自平衡树状数据结构,能对存储的数据进行O(log n)的时间复杂度进行查找.插入和删除.B树一般较多用在存储系统上,比如数 ...
- 19-看图理解数据结构与算法系列(Radix树)
Radix树 Radix树,即基数树,也称压缩前缀树,是一种提供key-value存储查找的数据结构.与Trie不同的是,它对Trie树进行了空间优化,只有一个子节点的中间节点将被压缩.同样的,Rad ...
- 13-看图理解数据结构与算法系列(Trie树)
Trie树 Trie树,是一种搜索树,也称字典树或单词查找树,此外也称前缀树,因为某节点的后代存在共同的前缀.它的key都为字符串,能做到高效查询和插入,时间复杂度为O(k),k为字符串长度,缺点是如 ...
- 10-看图理解数据结构与算法系列(B+树)
B+树 B+树是B树的一种变体,也属于平衡多路查找树,大体结构与B树相同,包含根节点.内部节点和叶子节点.多用于数据库和操作系统的文件系统中,由于B+树内部节点不保存数据,所以能在内存中存放更多索引, ...
- 17-看图理解数据结构与算法系列(NoSQL存储-LSM树)
关于LSM树 LSM树,即日志结构合并树(Log-Structured Merge-Tree).其实它并不属于一个具体的数据结构,它更多是一种数据结构的设计思想.大多NoSQL数据库核心思想都是基于L ...
- 看图轻松理解数据结构与算法系列(NoSQL存储-LSM树) - 全文
<看图轻松理解数据结构和算法>,主要使用图片来描述常见的数据结构和算法,轻松阅读并理解掌握.本系列包括各种堆.各种队列.各种列表.各种树.各种图.各种排序等等几十篇的样子. 关于LSM树 ...
- 数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解
数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解 对数组有不了解的可以先看看我的另一篇文章,那篇文章对数组有很多详细的解析,而本篇文章则着重讲动态数组,另一篇文章链接 ...
- javascript实现数据结构与算法系列:栈 -- 顺序存储表示和链式表示及示例
栈(Stack)是限定仅在表尾进行插入或删除操作的线性表.表尾为栈顶(top),表头为栈底(bottom),不含元素的空表为空栈. 栈又称为后进先出(last in first out)的线性表. 堆 ...
随机推荐
- luogu P1309 瑞士轮【排序】
题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较低,但比赛过程往往十分 ...
- [POI2009]Tab
Description 2个n\(\times\)m矩阵,保证同一个矩阵中元素两两不同.问能否通过若干次交换两行或交换两列把第一个矩阵变成第二个. Input 第一行正整数T(1≤T≤10)表示数据组 ...
- 《effective java》中文第2版 note
,第15条[66]: 为不可变类提供静态工厂, eg : Integer/BigInteger 使用了静态工厂缓存了一些常用的实例, 通常 Integer -128 ~ +127. BigIntege ...
- 2019最新Android面试题
原文链接:https://blog.csdn.net/wen_haha/article/details/88362469版权声明:本文为博主原创文章,转载请附上博文链接! 前言 金三银四到来了,找工作 ...
- 安装JPype时出现的 Unable to find vcvarsall.bat
解决方案,在网上找到的,mark一下,亲测有效 C:/Python31/Lib/distutils目录下的msvc9compiler.py中 修改MSVCCompiler函数:vc_env = que ...
- iOS中的蓝牙
iOS中的蓝牙 概述 iOS中提供了4个框架用于实现蓝牙连接 1.GameKit.framework(用法简单) 只能用于iOS设备之间的同个应用内连接,多用于游戏(eg.拳皇,棋牌类),从iOS7开 ...
- Katalon Studio 安装 配置 简单使用
本教程只针对Katalon Studio进行演示操作. 一.下载 Katalon 官网下载地址:https://www.katalon.com/download/ (需要注册账号) 二.解压.配置 直 ...
- jsdk之微信分享流程
.步骤一:绑定域名 先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”. 备注:登录后可在“开发者中心”查看对应的接口权限. .步骤二:引入JS文件 在需要调用JS接口的页面 ...
- Swift 关键字 inout - 让值类型以引用方式传递
两种参数传递方式 值类型 传递的是参数的一个副本,这样在调用参数的过程中不会影响原始数据. 引用类型 把参数本身引用(内存地址)传递过去,在调用的过程会影响原始数据. 在 Swift 众多数据类型中, ...
- loadrunner 响应时间和TPS
例子:一个高速路有10个入口,每个入口每秒钟只能进1辆车 1.请问1秒钟最多能进几辆车? TPS=10 2.每辆车需要多长时间进行响应? reponse time = 1 3.改成20辆车 ...