使用单节点构成2-3-4树

本文介绍了如何使用单个结点来构建2-3-4树,包括树的结构、添加结点和删除结点的过程。在添加结点可能导致不满足大小属性时,会进行分裂操作;删除结点后,若外部结点不在同一深度,会有两种处理方式:兄弟结点非单结点和兄弟结点为单结点。同时提供了相关操作的代码实现。
摘要由CSDN通过智能技术生成

2-3-4树

	2-3-4树称为(2,4)树,满足两点:
	·大小属性:每个内部节点最多有4个孩子
	·深度属性:所有外部结点具有相同的深度

2-3-4树如图:
在这里插入图片描述
对2-3-4树的详细方法不进行叙述。
在树中使用单个结点搭建上图结构,令h3位_root,h1和h4非别为各自的_head结点。

单个结点图:

每个结点有四个指针
在这里插入图片描述

大致结构图:

保证每个节点的四个指针都指向其他结点或None
在这里插入图片描述

添加结点:

对应代码中的_up_split方法

如果添加结点后导致不满足大小属性时进行分裂操作:
在这里插入图片描述
如图此时k1,k2,k3,k4以k1为head,但此时不满足大小属性,将k3分裂添加到h1后。
在这里插入图片描述
分裂后:
在这里插入图片描述

删除结点:

对应代码中的_down_split方法

如果删除后导致外部结点不在同一深度时,有两种情况。

Case1: 兄弟结点不为单结点
在这里插入图片描述
此时将被删除结点、父节点、兄弟结点进行如下交换:
在这里插入图片描述
交换后为:
在这里插入图片描述

Case2 兄弟结点为单结点
在这里插入图片描述
此时将结点14和15做如下结点交换并合并连接:
在这里插入图片描述
操作后,在将结点11与原15结点位置交换,再将两结点合并连接:
在这里插入图片描述
结果为:
在这里插入图片描述

代码(附有操作方法)

class TreeMap2_3_4:
    BLANK=object()                  # in down_split method, substitute other node
    class Position:
        ''' position class'''
        def __init__(self,node,container):
            self._node=node
            self._container=container

        def element(self):
            ''' return value of position '''
            return self._node._value

        def key(self):
            return self._node._key

        def __eq__(self,other):
            return type(self)==type(other) and self._node is other._node
    #
    class _Node:
        ''' creat the link node,'''
        def __init__(self,k,v,before=None,after=None,parent=None,child=None):
            self._key=k
            self._value=v
            self._before=before
            self._after=after
            self._parent=parent
            self._child=child
        #--------------------------convennient the node------------------------        
        def __eq__(self,k):
            ''' return true, if k==self._key'''
            if type(k) ==int:
                return self._key==k
            elif isinstance(k,type(self)):
                return self._key==k._key
            
        def __nq__(self,k):
            return not self==k

        def __lt__(self,k):
            ''' return true if k < self._key'''
            if type(k) ==int:
                return self._key<k
            elif isinstance(k,type(self)):
                return self._key<k._key
        
        def __gt__(self,k):
            return not self<k and self!=k

        def __le__(self,k):
            return self<k or self == k

        def __ge__(self, k):
            return self>k or self ==k
    #--------------------------------
    def __init__(self):
        ''' root return the first node'''
        self._root=None
        self._size=0

    def _validate(self,p):
        ''' Return associated node, if position is valid.'''
        if not isinstance(p, self.Position):
            raise TypeError('p must be proper Position type')
        if p._container is not self:
            raise ValueError('p does not belong to this container')
        if p._node._parent is p._node:      # convention for deprecated nodes
            raise ValueError('p is no longer valid')
        return p._node

    def _make_position(self,node):
        ''' return position of node '''
        return self.Position(node,self) if node != None else None
    
    def _add_after(self,p,temp,head_node=None):
        ''' add a node after p,p is Position class;
            reconect node's after,before parent,without child.
        '''
        node=self._validate(p)
        # temp's before is node,after is node's after
        #,parent is node's parent
        temp._before=node
        temp._after=node._after
        temp._parent=node._parent
        node._after = temp
        if temp._after is not None:
            temp._after._before=temp
        if head_node is not None:
            while temp is not None:  # repoint child's parent,_add_beofre method can't repoint
                subnode = temp._child
                while subnode is not None:
                    subnode._parent = head_node
                    subnode = subnode._after
                temp = temp._after
        return self._make_position(temp)

    def _add_before(self,p,temp,head_node=None):
        ''' this method can only be used for p which before node is none;
            add a node before p,p is Position and head node;
            temp is a _Node;
            head_node is _Node class;
            reconnect node's child,parent'before and after.
        '''
        node=self._validate(p)
        # temp's before is node._before,after is node,
        #parent is node._parent
        if temp._before is not None and temp._child is None:  # in case 2.1 of down_split method
            temp._child=node._before
        else:
            temp._before=node._before
        temp._after=node
        temp._parent=node._parent
        node._before=temp
        parent=self.parent(p)
        if parent is None:
            self._root=temp
        else:
            parent=self._validate(parent)
            if parent._before is node:
                parent._before = temp
            if parent._child is node:
                parent._child = temp
        tempnode=temp
        if head_node is not None:
            while tempnode is not None:  # repoint child's parent,
                subnode = tempnode._child
                while subnode is not None:
                    subnode._parent = head_node
                    subnode = subnode._after
                tempnode = tempnode._after
        return self._make_position(temp)   # now temp is the head
    
    def _add(self,p,k,v,head):
        ''' add a node in a proper posiiton '''
        node=self._validate(p)
        temp=self._Node(k,v)
        self._size+=1
        if node < k:
            self._add_after(p,temp)
            self._up_split(head)
        else:
            self._up_split(self._add_before(p,temp,temp))

    def _search(self,k,head=None,node=None):
        ''' return the proper Position and head if chain's child is None;
            find begin of root if node is None
            head and node are _Node class
        '''
        if node is None:
            node=self._root
            head=node
        #print(node,k,self._root)
        if node>k:                  # recursion to node's before
            if node._before is None:# break the cursion if there is none child
                return self._make_position(node),self._make_position(head)
            return self._search(k,node._before,node._before)
        if node==k:                 # break the cursion
            return self._make_position(node),self._make_position(head)
        if node<k:                  # recursion to node's after
            if node._after is not None:     # if there is item after node
                if k<node._after:           # node<k<node._after
                    if node._child is None: # node is the last node
                        return self._make_position
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值