当前位置:

首页 > 编程开发 > Python代码实现B+树的原理及详细实现

Python代码实现B+树的原理及详细实现

B+树是自平衡树的高级形式,其中所有值都存在于叶级中。B+树所有叶子都处于同一水平,每个节点的子节点数量≥2。B+树与B树的区别是各节点在B树上不是相互连接,而在B+树上是相互连接的。B+树多级索引结构图B+树搜索规则1、从根节点开始。将k与根节点的键进行比较[k1,k2,k3,......k(m-1)]2、如果k<k1,到根节点的左子节点;3、如果k==k1,再和ķ2比较.,如果k<k2,k介于ķ1和ķ2之间,在左子节点中搜索ķ24、如果k>k2,继续和k3,k4,...k(m-1)比

本文目录

    B+树是自平衡树的高级形式,其中所有值都存在于叶级中。B+树所有叶子都处于同一水平,每个节点的子节点数量≥2。B+树与B树的区别是各节点在B树上不是相互连接,而在B+树上是相互连接的。

    B+树多级索引结构图

    B+树原理 Python实现B+树详细代码

    B+树搜索规则

    1、从根节点开始。将k与根节点的键进行比较[k1,k2,k3,......k(m-1)]

    2、如果k

    3、如果k==k1,再和ķ2比较.,如果k

    4、如果k>k2,继续和k3,k4,...k(m-1)比较,重复如第2步和第3步

    5、直到节点中存在k,则返回true,否则返回false。

    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]]
    
    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
    
    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")
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    Python实现B+树删除操作的代码
    Python实现B+树删除操作的代码

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

    Python代码详解:B树删除操作
    Python代码详解:B树删除操作

    B树删除操作需要考虑节点所在位置和平衡,并且很有可能会发生下溢的情况。当一个节点包含的子节点数量少于它应该持有的最小数量时,就会发生下溢。图文展示B树删除操作原理在不影响平衡情况下。下溢情况。删除内部节点。Python实现B树删除操作#B树节点classBTreeNode:def__init__(self,leaf=False):self.leaf=leafself.keys=[]self.child=[]classBTree:def__init__(self,t):self.root=BTreeNode

    使用Python实现B树插入操作的原理图解
    使用Python实现B树插入操作的原理图解

    B树是高度平衡的二叉搜索树,进行插入操作,要先获取插入节点的位置,遵循节点比左子树大,比右子树小,在需要时拆分节点。一图看懂B树插入操作原理B树插入算法BreeInsertion(T,k)rroot[T]ifn[r]=2t-1s=AllocateNode()root[T]=sleaf[s]=FALSEn[s]<-0c1[s]<-rBtreeSplitChild(s,1,r)BtreeInsertNonFull(s,k)elseBtreeInsertNonFull(r,k)BtreeInsert

    数据库中B树索引的工作原理
    数据库中B树索引的工作原理

    数据库会使用一些方式来存储、读取和修改数据,在实际的数据库管理中,数据库会同时使用B-tree和B+tree来存储数据。其中B-tree用于索引,B+tree用于存储实际记录。本文带来B-tree在数据库中的索引机制。B-tree即B树,它是一种数据架构,是MySQL的一种索引类型,以一定顺序排列的节点的形式存储数据。B-tree存储数据的方式是每个节点按升序存储键,每个键包含2个指向其前后节点的链接。左边节点的key小于等于当前节点的key,右边节点的key大于等于当前节点的key。如果一个节点有n个键

    插入操作的Python代码实现B+树
    插入操作的Python代码实现B+树

    B+树插入操作需要考虑节点和平衡,如果是空树,按递增顺序将key插入叶子节点;如果不是空树,需要区分索引节点和叶子节点,不满足条件时还要对节点进行分解。Python实现B+树插入操作importmath#创建节点classNode:def__init__(self,order):self.order=orderself.values=[]self.keys=[]self.nextKey=Noneself.parent=Noneself.check_leaf=Falsedefinsert_at_leaf(s

    Python实现B树的详细解析
    Python实现B树的详细解析

    B树,和二叉搜索树很像,每个节点可以包含多个节点,但B树的子节点可以超过两个。B树数据结构B树可以在单个节点中存储许多键,并且可以有多个子节点。B树搜索算法BtreeSearch(x,k)i=1whilei≤n[x]andk≥keyi[x]doi=i+1ifin[x]andk=keyi[x]thenreturn(x,i)ifleaf[x]thenreturnNILelsereturnBtreeSearch(ci[x],k)B树搜索示例指定K=17,从根节点开始,将k与根进行比较。ķ>11,转到根的右

    opencode安装skills教程及本地配置方法
    opencode安装skills教程及本地配置方法

    遇到OpenCode Skills无法加载或配置无效?本文手把手教你完成Skills的安装、环境变量设置及本地调试,避开常见坑点,让AI助手更懂你的代码习惯。

    如何开启Visual Studio2022实时代码分析警告提示
    如何开启Visual Studio2022实时代码分析警告提示

    解决 Visual Studio 2022 编辑时不显示代码分析警告的问题。指南涵盖 .NET 项目实时分析设置、Roslyn 分析器范围调整及错误列表来源筛选,确保开发者能高效利用实时代码诊断功能。

    如何在Visual Studio2022查看变量监视窗口调试程序
    如何在Visual Studio2022查看变量监视窗口调试程序

    详解 Visual Studio 2022 调试技巧:包括断点设置、监视窗口开启方法、变量添加步骤以及通过 F10 单步执行观察变量值变化的全过程。

    Visual Studio2017设置默认编码为UTF-8不带BOM
    Visual Studio2017设置默认编码为UTF-8不带BOM

    针对 Visual Studio 2017 缺乏全局默认编码选项的情况,详解如何利用 .editorconfig 设定项目级 UTF-8 无 BOM 规则,以及手动转换现有文件并校验字节的方法。

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

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

    Windows
    Windows

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

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。