def fusion(self, tree_node, tree_fusion_node, left=True): """It performs fusion between adjacent nodes in order to resolve underflow conditions""" # if left == True s is at left of w w = tree_node s = tree_fusion_node u = w._parent p_parent = w._list_parent._node._parent #if left else w._list_parent._node._parent tree = RedBlackTreeMap() p = tree.add( p_parent.key()) # To obtain a position of a generic RBTree if left: w.tree().catenate(w._tree, p, left=False, T2=s._tree) w.tree()._l.fusion(s._tree._l, right=True) root = w.tree().root() left = w.tree().left(root) right = w.tree().right(root) w.tree()._update_black_height(left if left is not None else right) self.check_overflow(w) else: s.tree().catenate(s._tree, p, left=True, T2=w._tree) s.tree()._l.fusion(w._tree._l, right=False) root = s.tree().root() left = s.tree().left(root) right = s.tree().right(root) s.tree()._update_black_height(left if left is not None else right) self.check_overflow(s) #s.tree().add(p_parent.key()) del (u.tree()[p.key()])
def test_catenate(self): tree = self._T p50 = tree.add(50) p30 = tree.add(30) p60 = tree.add(60) p25 = tree.add(25) p35 = tree.add(35) tree2 = RedBlackTreeMap() p20 = tree2.add(20) tree3 = RedBlackTreeMap() p10 = tree3.add(10) p5 = tree3.add(5) p15 = tree3.add(15) l = [p50, p20, p60, p10, p30, p5, p15, p25, p35] tree.catenate(tree, pivot=tree2.root(), T2=tree3) for i, pos in enumerate(tree.breadthfirst()): self.assertEqual(pos, l[i]) tree4 = RedBlackTreeMap() p70 = tree4.add(70) tree5 = RedBlackTreeMap() p80 = tree5.add(80) p75 = tree5.add(75) p85 = tree5.add(85) tree.catenate(tree, pivot=tree4.root(), T2=tree5, left=False) l = [p50, p20, p70, p10, p30, p60, p80, p5, p15, p25, p35, p75, p85] for i, pos in enumerate(tree.breadthfirst()): self.assertEqual(pos, l[i]) print(pos.key(), " = ", l[i].key())
def split(self, tree_node): """It splits the external B-Tree node, recalling the same internal operation""" p = tree_node.tree()._get_median() #split operation, called on internal BSTs, returns the obtained subtrees if tree_node._parent is None: T1, T2 = tree_node.tree().split(p) else: T1, T2 = tree_node.tree().split(p) #parent = tree_node._parent #tree_node._parent = tree_node #Creo un nuovo albero node_left = self.Node(T1) node_right = self.Node(T2) if tree_node._parent is None: #Sono la radice tree_parent = RedBlackTreeMap() np = tree_parent.add(p.key()) node_parent = self.Node(tree_parent) self._root = node_parent tree_node._parent = tree_node #parent-children references settings np._node._left_out._node._child = node_left node_left._parent = node_parent node_left._list_parent = np._node._left_out self._update_children(node_left) #parent-children references settings np._node._right_out._node._child = node_right node_right._parent = node_parent node_right._list_parent = np._node._right_out self._update_children(node_right) self._num_node += 2 #parent._child = node_parent else: node_parent = tree_node._parent new_p = node_parent.tree().add(p.key()) #parent-children references settings new_p._node._left_out._node._child = node_left node_left._parent = node_parent node_left._list_parent = new_p._node._left_out self._update_children(node_left) #parent-children references settings new_p._node._right_out._node._child = node_right node_right._parent = node_parent node_right._list_parent = new_p._node._right_out self._update_children(node_right) self._num_node += 1 self.check_overflow(node_parent)