了解B树的删除

article/2025/9/8 23:43:20

文章目录

          • 1. 删除操作
            • 第一种情况
            • 第二种情况
            • 第三种情况
          • 2. C示例
          • 3. 删除复杂度
          • 参考文档

    在本教程中,您将学习如何从B树中删除键。此外,您还可以找到C语言的示例。
    删除B树上的元素包括三个主要事件:搜索要删除的键所在的节点、删除键和平衡树(如果需要)。
    删除树时,可能会出现一种称为下溢的情况。当一个节点包含的键少于它应该持有的最小键数时,就会发生下溢。
    在研究删除操作之前需要理解的术语是:

  1. 中序前置
    节点左子节点上最大的键称为其中序前置。
  2. 中序后置
    节点右子节点上的最小键称为其中序后置。
1. 删除操作

    在完成下面的步骤之前,你必须知道关于m度B树的这些事实。(m可理解为子级数)

  1. 一个节点最多可以有m个子节点。
  2. 一个节点最多可以包含m-1个键。
  3. 一个节点至少应有 ⌈m/2⌉ 个子节点。
  4. 节点(根节点除外)至少应包含⌈m/2⌉-1个键。

    B树中的删除操作主要有三种情况。

第一种情况

    要删除的键位于叶中。有两种情况。

  1. 删除健不会违反节点应持有的最小健数的属性。
    在下面的树中,删除32并不违反上述属性。
    在这里插入图片描述
  2. 删除键违反了节点应持有的最小键数的属性。在这种情况下,我们按照从左到右的顺序从紧邻的兄弟节点借用一个键。
    首先,去拜访他的左侧兄弟节点。如果左侧同级节点的键数超过最小值,则从该节点借用键。
    否则,尝试从紧邻的右侧同级节点借用。
    在下面的树中,删除31会导致上述情况。让我们从左侧同级节点借用一个键。
    在这里插入图片描述
        如果两个直接同级节点的键数都已达到最小值,则将该节点与左侧同级节点或右侧同级节点合并,这个合并是通过父节点完成的。
        删除30会导致上述结果。
    在这里插入图片描述
第二种情况

    如果要删除的键位于内部节点中,则会发生以下情况。

  1. 如果左子节点的键数超过最小值,则删除的内部节点将替换为中序前置节点。
    在这里插入图片描述
  2. 如果右子节点的键数超过最小值,则删除的内部节点将替换为中序后置节点。
  3. 如果任一子级的键数正好是最小的,则合并左子级和右子级。
    在这里插入图片描述

    合并后,如果父节点的键数小于最小值,则查找同级,如第一种情况所示。

第三种情况

    在这种情况下,树的高度会缩小。如果目标键位于内部节点中,并且删除该键会导致节点中的键数量减少(即,少于所需的最小值),则查找中序前置和中序后置。如果两个子项都包含最少数量的键,则不能进行借用。这导致了第二种情况(3),即合并孩子。
    再说一遍,找兄弟同级借键。但是,如果同级也只有最少数量的键,则将节点与同级以及父级合并。把孩子们按顺序排列好。
在这里插入图片描述

2. C示例
// Deleting a key from a B-tree in C#include <stdio.h>
#include <stdlib.h>#define MAX 3
#define MIN 2struct BTreeNode {int item[MAX + 1], count;struct BTreeNode *linker[MAX + 1];
};struct BTreeNode *root;// Node creation
struct BTreeNode *createNode(int item, struct BTreeNode *child) {struct BTreeNode *newNode;newNode = (struct BTreeNode *)malloc(sizeof(struct BTreeNode));newNode->item[1] = item;newNode->count = 1;newNode->linker[0] = root;newNode->linker[1] = child;return newNode;
}// Add value to the node
void addValToNode(int item, int pos, struct BTreeNode *node,struct BTreeNode *child) {int j = node->count;while (j > pos) {node->item[j + 1] = node->item[j];node->linker[j + 1] = node->linker[j];j--;}node->item[j + 1] = item;node->linker[j + 1] = child;node->count++;
}// Split the node
void splitNode(int item, int *pval, int pos, struct BTreeNode *node,struct BTreeNode *child, struct BTreeNode **newNode) {int median, j;if (pos > MIN)median = MIN + 1;elsemedian = MIN;*newNode = (struct BTreeNode *)malloc(sizeof(struct BTreeNode));j = median + 1;while (j <= MAX) {(*newNode)->item[j - median] = node->item[j];(*newNode)->linker[j - median] = node->linker[j];j++;}node->count = median;(*newNode)->count = MAX - median;if (pos <= MIN) {addValToNode(item, pos, node, child);} else {addValToNode(item, pos - median, *newNode, child);}*pval = node->item[node->count];(*newNode)->linker[0] = node->linker[node->count];node->count--;
}// Set the value in the node
int setValueInNode(int item, int *pval,struct BTreeNode *node, struct BTreeNode **child) {int pos;if (!node) {*pval = item;*child = NULL;return 1;}if (item < node->item[1]) {pos = 0;} else {for (pos = node->count;(item < node->item[pos] && pos > 1); pos--);if (item == node->item[pos]) {printf("Duplicates not allowed\n");return 0;}}if (setValueInNode(item, pval, node->linker[pos], child)) {if (node->count < MAX) {addValToNode(*pval, pos, node, *child);} else {splitNode(*pval, pval, pos, node, *child, child);return 1;}}return 0;
}// Insertion operation
void insertion(int item) {int flag, i;struct BTreeNode *child;flag = setValueInNode(item, &i, root, &child);if (flag)root = createNode(i, child);
}// Copy the successor
void copySuccessor(struct BTreeNode *myNode, int pos) {struct BTreeNode *dummy;dummy = myNode->linker[pos];for (; dummy->linker[0] != NULL;)dummy = dummy->linker[0];myNode->item[pos] = dummy->item[1];
}// Remove the value
void removeVal(struct BTreeNode *myNode, int pos) {int i = pos + 1;while (i <= myNode->count) {myNode->item[i - 1] = myNode->item[i];myNode->linker[i - 1] = myNode->linker[i];i++;}myNode->count--;
}// Do right shift
void rightShift(struct BTreeNode *myNode, int pos) {struct BTreeNode *x = myNode->linker[pos];int j = x->count;while (j > 0) {x->item[j + 1] = x->item[j];x->linker[j + 1] = x->linker[j];}x->item[1] = myNode->item[pos];x->linker[1] = x->linker[0];x->count++;x = myNode->linker[pos - 1];myNode->item[pos] = x->item[x->count];myNode->linker[pos] = x->linker[x->count];x->count--;return;
}// Do left shift
void leftShift(struct BTreeNode *myNode, int pos) {int j = 1;struct BTreeNode *x = myNode->linker[pos - 1];x->count++;x->item[x->count] = myNode->item[pos];x->linker[x->count] = myNode->linker[pos]->linker[0];x = myNode->linker[pos];myNode->item[pos] = x->item[1];x->linker[0] = x->linker[1];x->count--;while (j <= x->count) {x->item[j] = x->item[j + 1];x->linker[j] = x->linker[j + 1];j++;}return;
}// Merge the nodes
void mergeNodes(struct BTreeNode *myNode, int pos) {int j = 1;struct BTreeNode *x1 = myNode->linker[pos], *x2 = myNode->linker[pos - 1];x2->count++;x2->item[x2->count] = myNode->item[pos];x2->linker[x2->count] = myNode->linker[0];while (j <= x1->count) {x2->count++;x2->item[x2->count] = x1->item[j];x2->linker[x2->count] = x1->linker[j];j++;}j = pos;while (j < myNode->count) {myNode->item[j] = myNode->item[j + 1];myNode->linker[j] = myNode->linker[j + 1];j++;}myNode->count--;free(x1);
}// Adjust the node
void adjustNode(struct BTreeNode *myNode, int pos) {if (!pos) {if (myNode->linker[1]->count > MIN) {leftShift(myNode, 1);} else {mergeNodes(myNode, 1);}} else {if (myNode->count != pos) {if (myNode->linker[pos - 1]->count > MIN) {rightShift(myNode, pos);} else {if (myNode->linker[pos + 1]->count > MIN) {leftShift(myNode, pos + 1);} else {mergeNodes(myNode, pos);}}} else {if (myNode->linker[pos - 1]->count > MIN)rightShift(myNode, pos);elsemergeNodes(myNode, pos);}}
}// Delete a value from the node
int delValFromNode(int item, struct BTreeNode *myNode) {int pos, flag = 0;if (myNode) {if (item < myNode->item[1]) {pos = 0;flag = 0;} else {for (pos = myNode->count; (item < myNode->item[pos] && pos > 1); pos--);if (item == myNode->item[pos]) {flag = 1;} else {flag = 0;}}if (flag) {if (myNode->linker[pos - 1]) {copySuccessor(myNode, pos);flag = delValFromNode(myNode->item[pos], myNode->linker[pos]);if (flag == 0) {printf("Given data is not present in B-Tree\n");}} else {removeVal(myNode, pos);}} else {flag = delValFromNode(item, myNode->linker[pos]);}if (myNode->linker[pos]) {if (myNode->linker[pos]->count < MIN)adjustNode(myNode, pos);}}return flag;
}// Delete operaiton
void delete (int item, struct BTreeNode *myNode) {struct BTreeNode *tmp;if (!delValFromNode(item, myNode)) {printf("Not present\n");return;} else {if (myNode->count == 0) {tmp = myNode;myNode = myNode->linker[0];free(tmp);}}root = myNode;return;
}void searching(int item, int *pos, struct BTreeNode *myNode) {if (!myNode) {return;}if (item < myNode->item[1]) {*pos = 0;} else {for (*pos = myNode->count;(item < myNode->item[*pos] && *pos > 1); (*pos)--);if (item == myNode->item[*pos]) {printf("%d present in B-tree", item);return;}}searching(item, pos, myNode->linker[*pos]);return;
}void traversal(struct BTreeNode *myNode) {int i;if (myNode) {for (i = 0; i < myNode->count; i++) {traversal(myNode->linker[i]);printf("%d ", myNode->item[i + 1]);}traversal(myNode->linker[i]);}
}int main() {int item, ch;insertion(8);insertion(9);insertion(10);insertion(11);insertion(15);insertion(16);insertion(17);insertion(18);insertion(20);insertion(23);traversal(root);delete (20, root);printf("\n");traversal(root);
}
3. 删除复杂度

最佳情况时间复杂度: Θ(log n)
平均情况空间复杂度: Θ(n)
最坏情况空间复杂度: Θ(n)

参考文档

[1]Parewa Labs Pvt. Ltd.Insertion into a B-tree[EB/OL].https://www.programiz.com/dsa/deletion-from-a-b-tree,2020-01-01.


http://chatgpt.dhexx.cn/article/ej6W3nB7.shtml

相关文章

B树的插入、删除操作

一、简介 B树是什么&#xff1f; 1970年&#xff0c;R.Bayer和E.mccreight提出了一种适用于外查找的树&#xff0c;它是一种平衡的多叉树&#xff0c;称为B树&#xff08;或B-树、B_树&#xff09;。 一棵m阶B树(balanced tree of order m)是一棵平衡的m路搜索树。它或者是空树…

数据结构-B树删除示例

数据结构学习-B树删除示例 1、B树简介2、在线可视化生成B树工具3、B树删除规则4、B树删除示例4.1、删除非根结点示例4.2、删除根结点示例 1、B树简介 1970年&#xff0c;R.Bayer和E.mccreight提出了一种适用于外查找的树&#xff0c;它是一种平衡的多叉树&#xff0c;称为B树&a…

B树-多路平衡查找树

B树 B树一个m阶B树的具有的特征&#xff08;或必须满足的条件&#xff09;B树的查找B树插入元素(一定是在叶子节点插入)1.插入后&#xff0c;没有破坏B树的规则2.插入后&#xff0c;叶子节点元素超过m-1个 B树删除元素1.删除叶子节点上的元素&#xff0c;没有破坏规则2.删除叶子…

B树、B+树详解

B-树&#xff0c;即为B树。因为B树的原英文名称为B-tree&#xff0c;目前理解B的意思为平衡。 概念 首先&#xff0c;B树不要和二叉树混淆&#xff0c;在计算机科学中&#xff0c;B树是一种自平衡树数据结构&#xff0c;它维护有序数据并允许以对数时间进行搜索&#xff0c;顺…

【B树及B树的基本操作】

文章目录 1.B树的定义和特性2.B树的性质3.B树创建的过程。4.B树的删除5.总结 1.B树的定义和特性 B树是一种平衡的多路查找树。 一棵m阶的B树&#xff08;B树中所有结点的孩子个数的最大值为m)&#xff0c;或为空树&#xff0c;或为满足下列特性的m叉树&#xff1a; (1) 树中每…

B树和B+树的区别

文章目录 简述写在前面1、B树2、B树 深入浅出B树B树深入B-树的查找 B 树B树概述 B-树和B树的区别拓展&#xff1a;MySQL为什么使用B-Tree&#xff08;BTree&#xff09;&& 存储知识存储数据最小单元主存存取原理磁盘存取原理 总结 简述 写在前面 大家在面试的时候&am…

B树(B-树)详解

B-树&#xff0c;即为B树。因为B树的原英文名称为B-tree&#xff0c;而国内很多人喜欢把B-tree译作B-树&#xff0c;B-tree就是指的B树。 B-树容易让人误解,建议大家用B树称呼, 本文以下直称B树 这篇介绍概念, 优点应用等, B树的描述和增删改查请到隔壁我写的另一篇(篇幅较长…

数据结构 —— B树

文章目录 1、B树的定义1.1、B树的特性1.2、B树的高度1.3、性能分析1.4、B树的补充说明1.5 、B树、B-树 、B-tree、B tree的区别 2、B树的插入操作以5阶B树为例&#xff0c;介绍B树的插入操作&#xff0c; 3、 B树的删除操作以5阶B树为例&#xff0c;介绍B树的删除操作 4、B树相…

B树和B+树详解

B树、B树看这一篇就够了 [TOC](B树、B树看这一篇就够了) 引言B树什么是B树以及B树是怎么来的B树的基本性质B树的新增和删除B树的插入B树的删除 B树什么是B树以及为什么要有B树B树的基本性质B树的查找 B树与B树的比较B树的优势B树的优势两者的细节对比 B树与B树在实际代码中的应…

B-树(B树)详解

https://www.jianshu.com/p/7dedb7ebe033 具体讲解之前&#xff0c;有一点&#xff0c;再次强调下&#xff1a;B-树&#xff0c;即为B树。因为B树的原英文名称为B-tree&#xff0c;而国内很多人喜欢把B-tree译作B-树&#xff0c;其实&#xff0c;这是个非常不好的直译&#xf…

B树和B+树

目录 一、BST树到AVL树到B树的简介 1.1 BST树 --- 二叉排序树 1.2 AVL树 --- 平衡二叉树 1.3 B树 --- 平衡多路查找树 1.3.1 B树的查找结点过程 1.3.2 B树的添加结点过程&#xff08;和结点分裂过程&#xff09; 1.3.3 B树的删除结点过程 二、B树 2.1 B树和B树 一…

在群晖NAS部署_开源在线项目任务管理工具【dooTask】

一、dooTask简介 1.1、说明 Dootask 是一款由国人开源的轻量级在线项目任务管理工具&#xff0c;它提供各类文档协作工具、在线思维导图、在线流程图、项目管理、任务分发、即时通讯IM&#xff0c;文件管理等功能。基于PHP与Vue编写&#xff0c;遵守AGPL3.0开源协议。 1.2、特…

软件项目管理的重点知识

软件项目管理的重点知识 1.软件项目管理概述 1.1项目是什么 项目是为了创造一个唯一的产品或提供一个唯一的服务而进行的临时性的努力。 1.2常见的项目 生活中的项目 生日聚会野餐活动集体婚礼 大项目 微软的操作系统阿波罗计划神州飞船计划鸿蒙操作系统开发一个网站运…

推荐八款好用的项目管理工具

要想取得项目成功&#xff0c;避不开包括计划、执行、监控等。使用项目管理工具可以帮助项目经理制定项目计划&#xff0c;监控项目执行&#xff0c;跟踪项目进度。 1、进度猫 进度猫是国产的一款项目管理工具以甘特图为向导&#xff0c;基于任务清单todolist&#xff0c;支持…

工程项目管理软件有哪些?这六款很好用!

工程项目管理软件哪个好用&#xff1f;这六款很不错&#xff01; 在现代社会中&#xff0c;软件已经成为了企业信息化、项目管理等方面必不可少的工具。尤其是对于工程项目管理而言&#xff0c;借助软件进行协同、计划、控制等方面的工作&#xff0c;已经成为了必要的手段。但…

项目管理-软件:国内外知名IT项目管理工具【Worktile、PingCode、Jira、Clarizen、禅道】

IT项目管理随着敏捷的普及&#xff0c;支持其开发模式的工具也越来越多。它和瀑布工具的巨大差异在于一个是任务管理模式&#xff0c;一个是需求驱动管理模式。在这里&#xff0c;我列出了在国内外最知名最好用的敏捷工具及其网站。IT项目管理&#xff0c;或者说研发管理软件是…

10款最佳项目管理工具推荐

1、进度猫 进度猫是一款以甘特图为向导的轻量级在线免费项目进度管理工具。 特点&#xff1a; 基于甘特图、进度管理、任务管理ToDo、在线思维导图、团队协作随时把控项目进度,让项目管理一目了然。 甘特图显示项目的进度和具体任务清单。 对未完成任务、已完成任务进行分类…

知乎热推 6 款在线项目管理工具测评

用了一段时间的项目管理工具后&#xff0c;简单的总结项目管理工具就是&#xff1a; 一个能够满足项目经理对项目资源&#xff08;人员、文件和时间&#xff09;的管理&#xff0c;同时提供了项目进度可视化展示和支持团队合作的平台工具。 在这里&#xff0c;对知乎上热推的几…

项目管理系统源码

项目管理系统源码 功能介绍&#xff1a; 1&#xff1a;权限管理 。 对公司人员&#xff0c;组织架构进行管理&#xff0c;对用户采用角色授权的方式控制结点、菜单权限 3&#xff1a;项目管理。 对一个项目可以进行分阶段&#xff0c;分任务…划分&#xff0c;对每个划分点…

说好求一款在线项目管理软件,你们为什么推荐钉钉?

作为一名整天被各种项目虐得发际线不断后移的项目经理&#xff0c;对于项目管理工具&#xff0c;我是认真的。然而&#xff0c;混迹某些交流群中&#xff0c;时不时碰到有人询问推荐在线项目管理工具&#xff0c;总有人出来说&#xff1a;钉钉。纳尼&#xff1f;钉钉在我眼里真…