当前位置:

首页 > 编程开发 > Python实现B+树删除操作的代码

Python实现B+树删除操作的代码

本文目录

    B+树删除操作需要先找到删除节点的位置,然后判断节点的键数。如果节点中的键数量超过了最小数量,直接删除即可。如下图,删除“40”:如果节点中有确切的最小键数,删除就需要从兄弟节点那里借用,将兄弟节点的中间键添加到父节点。如下图,删除“5”:删除内容节点,如果节点中的键数超过最小数量,只需从叶节点中删除该键,并从内部节点中删除该键。用中序后继填充内部节点中的空白区域。如下图,删除“45”:删除内容节点,如果节点中有确切的最小键数,则删除该键并直接从兄弟节点借用一个键,用借来的键填充索引中的空白空间。如下图,

    B+树删除操作需要先找到删除节点的位置,然后判断节点的键数。

    如果节点中的键数量超过了最小数量,直接删除即可。

    如下图,删除“40”:

    Python代码实现B+树删除操作

    如果节点中有确切的最小键数,删除就需要从兄弟节点那里借用,将兄弟节点的中间键添加到父节点。如下图,删除“5”:

    Python代码实现B+树删除操作

    删除内容节点,如果节点中的键数超过最小数量,只需从叶节点中删除该键,并从内部节点中删除该键。用中序后继填充内部节点中的空白区域。如下图,删除“45”:

    Python代码实现B+树删除操作

    删除内容节点,如果节点中有确切的最小键数,则删除该键并直接从兄弟节点借用一个键,用借来的键填充索引中的空白空间。如下图,删除“35”:

    Python代码实现B+树删除操作

    删除内容节点,在父节点上方生成空白空间。删除键后,将空白空间与其兄弟节点合并,用中序后继填充父节点中的空白空间。如下图,删除“25”:

    Python代码实现B+树删除操作

    导致树高度会缩小的删除操作,如下图,删除“55”:

    Python代码实现B+树删除操作

    Python实现B+树删除操作

    import math
    # 创建节点
    class Node:
        def __init__(self, order):
            self.order = order
            self.values = []
            self.keys = []
            self.nextKey = None
            self.parent = None
            self.check_leaf = False
    
    # 插入叶子
        def insert_at_leaf(self, leaf, value, key):
            if (self.values):
                temp1 = self.values
                for i in range(len(temp1)):
                    if (value == temp1[i]):
                        self.keys[i].append(key)
                        break
                    elif (value < temp1[i]):
                        self.values = self.values[:i] + [value] + self.values[i:]
                        self.keys = self.keys[:i] + [[key]] + self.keys[i:]
                        break
                    elif (i + 1 == len(temp1)):
                        self.values.append(value)
                        self.keys.append([key])
                        break
            else:
                self.values = [value]
                self.keys = [[key]]
    
    
    # B+树
    class BplusTree:
        def __init__(self, order):
            self.root = Node(order)
            self.root.check_leaf = True
    
        # 插入节点
        def insert(self, value, key):
            value = str(value)
            old_node = self.search(value)
            old_node.insert_at_leaf(old_node, value, key)
    
            if (len(old_node.values) == old_node.order):
                node1 = Node(old_node.order)
                node1.check_leaf = True
                node1.parent = old_node.parent
                mid = int(math.ceil(old_node.order / 2)) - 1
                node1.values = old_node.values[mid + 1:]
                node1.keys = old_node.keys[mid + 1:]
                node1.nextKey = old_node.nextKey
                old_node.values = old_node.values[:mid + 1]
                old_node.keys = old_node.keys[:mid + 1]
                old_node.nextKey = node1
                self.insert_in_parent(old_node, node1.values[0], node1)
    
        def search(self, value):
            current_node = self.root
            while(current_node.check_leaf == False):
                temp2 = current_node.values
                for i in range(len(temp2)):
                    if (value == temp2[i]):
                        current_node = current_node.keys[i + 1]
                        break
                    elif (value < temp2[i]):
                        current_node = current_node.keys[i]
                        break
                    elif (i + 1 == len(current_node.values)):
                        current_node = current_node.keys[i + 1]
                        break
            return current_node
    
        # 查找节点
        def find(self, value, key):
            l = self.search(value)
            for i, item in enumerate(l.values):
                if item == value:
                    if key in l.keys[i]:
                        return True
                    else:
                        return False
            return False
    
        # 在父级插入
        def insert_in_parent(self, n, value, ndash):
            if (self.root == n):
                rootNode = Node(n.order)
                rootNode.values = [value]
                rootNode.keys = [n, ndash]
                self.root = rootNode
                n.parent = rootNode
                ndash.parent = rootNode
                return
    
            parentNode = n.parent
            temp3 = parentNode.keys
            for i in range(len(temp3)):
                if (temp3[i] == n):
                    parentNode.values = parentNode.values[:i] + \
                        [value] + parentNode.values[i:]
                    parentNode.keys = parentNode.keys[:i +
                                                      1] + [ndash] + parentNode.keys[i + 1:]
                    if (len(parentNode.keys) > parentNode.order):
                        parentdash = Node(parentNode.order)
                        parentdash.parent = parentNode.parent
                        mid = int(math.ceil(parentNode.order / 2)) - 1
                        parentdash.values = parentNode.values[mid + 1:]
                        parentdash.keys = parentNode.keys[mid + 1:]
                        value_ = parentNode.values[mid]
                        if (mid == 0):
                            parentNode.values = parentNode.values[:mid + 1]
                        else:
                            parentNode.values = parentNode.values[:mid]
                        parentNode.keys = parentNode.keys[:mid + 1]
                        for j in parentNode.keys:
                            j.parent = parentNode
                        for j in parentdash.keys:
                            j.parent = parentdash
                        self.insert_in_parent(parentNode, value_, parentdash)
    
        # 删除节点
        def delete(self, value, key):
            node_ = self.search(value)
    
            temp = 0
            for i, item in enumerate(node_.values):
                if item == value:
                    temp = 1
    
                    if key in node_.keys[i]:
                        if len(node_.keys[i]) > 1:
                            node_.keys[i].pop(node_.keys[i].index(key))
                        elif node_ == self.root:
                            node_.values.pop(i)
                            node_.keys.pop(i)
                        else:
                            node_.keys[i].pop(node_.keys[i].index(key))
                            del node_.keys[i]
                            node_.values.pop(node_.values.index(value))
                            self.deleteEntry(node_, value, key)
                    else:
                        print("Value not in Key")
                        return
            if temp == 0:
                print("Value not in Tree")
                return
    
        # 删除条目
        def deleteEntry(self, node_, value, key):
    
            if not node_.check_leaf:
                for i, item in enumerate(node_.keys):
                    if item == key:
                        node_.keys.pop(i)
                        break
                for i, item in enumerate(node_.values):
                    if item == value:
                        node_.values.pop(i)
                        break
    
            if self.root == node_ and len(node_.keys) == 1:
                self.root = node_.keys[0]
                node_.keys[0].parent = None
                del node_
                return
            elif (len(node_.keys) < int(math.ceil(node_.order / 2)) and node_.check_leaf == False) or (len(node_.values) < int(math.ceil((node_.order - 1) / 2)) and node_.check_leaf == True):
    
                is_predecessor = 0
                parentNode = node_.parent
                PrevNode = -1
                NextNode = -1
                PrevK = -1
                PostK = -1
                for i, item in enumerate(parentNode.keys):
    
                    if item == node_:
                        if i > 0:
                            PrevNode = parentNode.keys[i - 1]
                            PrevK = parentNode.values[i - 1]
    
                        if i < len(parentNode.keys) - 1:
                            NextNode = parentNode.keys[i + 1]
                            PostK = parentNode.values[i]
    
                if PrevNode == -1:
                    ndash = NextNode
                    value_ = PostK
                elif NextNode == -1:
                    is_predecessor = 1
                    ndash = PrevNode
                    value_ = PrevK
                else:
                    if len(node_.values) + len(NextNode.values) < node_.order:
                        ndash = NextNode
                        value_ = PostK
                    else:
                        is_predecessor = 1
                        ndash = PrevNode
                        value_ = PrevK
    
                if len(node_.values) + len(ndash.values) < node_.order:
                    if is_predecessor == 0:
                        node_, ndash = ndash, node_
                    ndash.keys += node_.keys
                    if not node_.check_leaf:
                        ndash.values.append(value_)
                    else:
                        ndash.nextKey = node_.nextKey
                    ndash.values += node_.values
    
                    if not ndash.check_leaf:
                        for j in ndash.keys:
                            j.parent = ndash
    
                    self.deleteEntry(node_.parent, value_, node_)
                    del node_
                else:
                    if is_predecessor == 1:
                        if not node_.check_leaf:
                            ndashpm = ndash.keys.pop(-1)
                            ndashkm_1 = ndash.values.pop(-1)
                            node_.keys = [ndashpm] + node_.keys
                            node_.values = [value_] + node_.values
                            parentNode = node_.parent
                            for i, item in enumerate(parentNode.values):
                                if item == value_:
                                    p.values[i] = ndashkm_1
                                    break
                        else:
                            ndashpm = ndash.keys.pop(-1)
                            ndashkm = ndash.values.pop(-1)
                            node_.keys = [ndashpm] + node_.keys
                            node_.values = [ndashkm] + node_.values
                            parentNode = node_.parent
                            for i, item in enumerate(p.values):
                                if item == value_:
                                    parentNode.values[i] = ndashkm
                                    break
                    else:
                        if not node_.check_leaf:
                            ndashp0 = ndash.keys.pop(0)
                            ndashk0 = ndash.values.pop(0)
                            node_.keys = node_.keys + [ndashp0]
                            node_.values = node_.values + [value_]
                            parentNode = node_.parent
                            for i, item in enumerate(parentNode.values):
                                if item == value_:
                                    parentNode.values[i] = ndashk0
                                    break
                        else:
                            ndashp0 = ndash.keys.pop(0)
                            ndashk0 = ndash.values.pop(0)
                            node_.keys = node_.keys + [ndashp0]
                            node_.values = node_.values + [ndashk0]
                            parentNode = node_.parent
                            for i, item in enumerate(parentNode.values):
                                if item == value_:
                                    parentNode.values[i] = ndash.values[0]
                                    break
    
                    if not ndash.check_leaf:
                        for j in ndash.keys:
                            j.parent = ndash
                    if not node_.check_leaf:
                        for j in node_.keys:
                            j.parent = node_
                    if not parentNode.check_leaf:
                        for j in parentNode.keys:
                            j.parent = parentNode
    
    
    # 输出B+树
    def printTree(tree):
        lst = [tree.root]
        level = [0]
        leaf = None
        flag = 0
        lev_leaf = 0
    
        node1 = Node(str(level[0]) + str(tree.root.values))
    
        while (len(lst) != 0):
            x = lst.pop(0)
            lev = level.pop(0)
            if (x.check_leaf == False):
                for i, item in enumerate(x.keys):
                    print(item.values)
            else:
                for i, item in enumerate(x.keys):
                    print(item.values)
                if (flag == 0):
                    lev_leaf = lev
                    leaf = x
                    flag = 1
    
    record_len = 3
    bplustree = BplusTree(record_len)
    bplustree.insert('5', '33')
    bplustree.insert('15', '21')
    bplustree.insert('25', '31')
    bplustree.insert('35', '41')
    bplustree.insert('45', '10')
    
    printTree(bplustree)
    
    if(bplustree.find('5', '34')):
        print("Found")
    else:
        print("Not found")
    本文内容来源于网友投稿,如有侵权请联系删除。
    作者最新文章
    编程开发
    相关文章 更多
    Java测试中怎么使用Mockito模拟依赖对象
    Java测试中怎么使用Mockito模拟依赖对象

    详细讲解在Java单元测试中如何使用Mockito模拟依赖对象,包括引入依赖、创建Mock、打桩返回值、行为验证以及Mock与Spy的核心差异和常见陷阱排查。

    链表删除节点的时间复杂度是多少及其详细分析
    链表删除节点的时间复杂度是多少及其详细分析

    详细分析链表删除节点的时间复杂度,深入探讨单链表与双向链表在不同已知前提下的查找与删除开销,并结合完整代码与清晰图解进行对比总结。

    codex如何配置模型参数及文件设置教程
    codex如何配置模型参数及文件设置教程

    想知道如何让AI写出的代码更贴合你的习惯?本文手把手教你在VS Code中调整Codex相关模型参数,通过修改配置文件优化温度值和令牌限制,解决代码建议不准确或响应慢的问题。

    Claude Code AI编程工具实力揭秘与编程助手实测
    Claude Code AI编程工具实力揭秘与编程助手实测

    通过实测展示Claude Code在终端中如何理解自然语言指令、自动修改代码文件并处理复杂编程任务,帮助开发者评估其实际辅助能力。

    winforms教程自学入门与基础开发步骤详解
    winforms教程自学入门与基础开发步骤详解

    本教程详细讲解如何使用Visual Studio创建WinForms项目,通过添加按钮和标签控件并编写点击事件代码,实现一个基础的计数器功能,适合C#初学者快速上手Windows窗体应用开发。

    Cursor自动补全设置教程教你快速开启代码补全功能
    Cursor自动补全设置教程教你快速开启代码补全功能

    详解Cursor编辑器中自动补全功能的开启与优化设置,涵盖Tab触发机制、上下文窗口调整及模型切换,帮助开发者解决补全延迟、干扰大等问题,提升编码流畅度。

    pandas的数据格式怎么转换和设置方法教程
    pandas的数据格式怎么转换和设置方法教程

    详解Pandas中数据格式转换的核心方法,包括astype强制转换、to_numeric容错处理及日期解析技巧,解决常见类型错误并提升数据处理效率。

    VS Code中文设置方法 简体语言包安装与切换教程
    VS Code中文设置方法 简体语言包安装与切换教程

    详细介绍在Visual Studio Code中安装Chinese (Simplified)语言包的方法,包括通过扩展市场搜索、安装及自动重启切换至简体中文界面的完整步骤,帮助开发者快速将编辑器本地化。

    cursor安装过程无法更改安装位置的解决方法
    cursor安装过程无法更改安装位置的解决方法

    针对Cursor安装包默认锁定C盘且无路径选择界面的问题,提供通过手动移动文件并创建目录联结(Symbolic Link)的解决方案,实现将软件安装在其他磁盘分区。

    rust下载安装教程详解及Windows环境配置方法
    rust下载安装教程详解及Windows环境配置方法

    详解Windows系统下Rust语言的安装步骤,重点解析rustup工具链管理机制,解决环境变量配置错误及MSVC链接器缺失问题,提供可复制的命令验证方法与常见报错的因果排查思路。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    macOS软件
    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    Mac软件 更多
    photoshop
    photoshop
    Windows、macOS 、 iPad

    Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。

    Blender
    Blender
    Windows、macOS 和 Linux

    Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。

    灵活计算器
    灵活计算器
    macOS/iOS/Android

    灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

    WINDOWS 更多
    3dmax(3ds max)
    3dmax(3ds max)
    Windows

    Autodesk 3ds Max 是一款专业的三维建模、动画与渲染软件,广泛应用于建筑可视化、游戏开发、影视动画、广告设计和产品展示等领域。

    photoshop
    photoshop
    Windows、macOS 、 iPad

    Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。

    Blender
    Blender
    Windows、macOS 和 Linux

    Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。