B+树查找操作的图形化展示,python调用graphviz自动生成svg图形

引言

在前面的文章《B+树删除操作的图形化展示,python调用graphviz自动生成svg图形》中用图形化的方式展示了B+树在删除时图形的变化。

本文用来展示B+树查找操作的过程。

在网上查到一篇文献《关于 B+tree (附 python 模拟代码)》。该文作者用python实现了B+树的基本操作。但是他的输出结果是文本形式的,不方便直观地查看B+树的动态变化效果。本文在原作者python代码的基础上做了一些改进,实现了图形化展示的效果。对原作者的分享精神,再次表示感谢。

原作者代码与python3不兼容,为了在最新的python3.7上运行代码,对代码做了相应的改进

图形化显示环境的搭建细节,还请参看以前的文章《平衡二叉树插入及删除操作的图形化展示,python调用graphviz自动生成svg图形》
对svg图形做美化处理的细节,还请参看以前的文章《用jquery对graphviz生成的svg图形做后处理,改变字体,颜色,连线形状等》

图形化效果

下面是加载一棵B+树后,进行查找操作的图文演示
B+树查找操作的图形化展示,python调用graphviz自动生成svg图形_第1张图片

进行查找的python代码

#在树上查找
    def search(self,mi=None,ma=None):
        result=[]
        node=self.__root
        leaf=self.__leaf

        if mi is None and ma is None:
            raise (ParaError,'you need to setup searching range')

        elif mi is not None and ma is not None and mi>ma:
            raise( ParaError,'upper bound must be greater or equal than lower bound')
        
        def search_key(n,k):
            tipInfo('对 #%s 号节点进行检查 '%(n.id))
            if n.isleaf():
                tipInfo(' #%s 号节点是叶子节点 '%(n.id))
                p=bisect_left(n.kvList,k)
                tipInfo(' #%s 号节点中的发现键值 %s 的位置 %s '%(n.id,k.key,p))
                return (p,n)
            else:
                tipInfo(' #%s 号节点是内部节点 '%(n.id))
                p=bisect_right(n.indexList,k.key)
                tipInfo(' #%s 号节点中的发现键值 %s 的位置 %s '%(n.id,k.key,p))
                return search_key(n.childList[p],k)

        #如果未指定下限
        if mi is None:
            ma = KeyValue(ma,'')
            while True:
                for kv in leaf.kvList:
                    if kv<=ma:
                        result.append(kv)
                    else:
                        return result
                if leaf.bro:
                    leaf=leaf.bro
                else:                    
                    return result

        #如果未指定上限
        elif ma is None:
            mi = KeyValue(mi,'')
            index,leaf=search_key(node,mi)
            result.extend(leaf.kvList[index:])
            while True:
                if leaf.bro :
                    leaf=leaf.bro
                    result.extend(leaf.kvList)
                else:
                    return result                    

        #指定了上下限
        else:
            mi = KeyValue(mi,'')
            ma = KeyValue(ma,'')
            if mi==ma:
                i,l=search_key(node,mi)
                try:
                    if l.kvList[i]==mi:
                        result.append(l.kvList[i])
                        return result
                    else:
                        return result
                except IndexError:
                    return result
            else:
                i1,l1=search_key(node,mi)
                i2,l2=search_key(node,ma)

                if l1 is l2:
                    if i1==i2:
                        return result
                    else:
                        result.extend(l1.kvList[i1:i2])
                        return result
                else:
                    result.extend(l1.kvList[i1:])
                    l=l1
                    while True:
                        if l.bro==l2:
                            if i2 >= len(l2.kvList):
                                # ma 比 l2.kvList中的所有值都要大
                                result.extend(l2.kvList[:i2])
                            else:
                                if ma < l2.kvList[i2] :
                                    #ma 比l2.kvList[i2]小,则l2.kvList[i2]应排除掉,切片操作的右边是开集
                                    result.extend(l2.kvList[:i2])
                                else:
                                    #ma 与 l2.kvList[i2]相等,则要包括l2.kvList[i2]                               
                                    result.extend(l2.kvList[:i2+1])
                            return result
                        else:
                            t = l.bro
                            result.extend(t.kvList)
                            l=t

你可能感兴趣的:(python,编程语言,B+树,查找操作,python,graphviz,svg)