Example #1
0
def effective_os_delete(T, z):
    if z.left is T.nil or z.right is T.nil:
        y = z
    else:
        y = rb_successor(z, T.nil)
    p = rb_predecessor(y, T.nil)
    s = rb_successor(y, T.nil)
    if y.left is not T.nil:
        x = y.left
    else:
        x = y.right
    x.p = y.p
    if y.p is T.nil:
        T.root = x
    else:
        if y is y.p.left:
            y.p.left = x
        else:
            y.p.right = x
    if y is not z:
        z.key = y.key
        z.data = y.data
    w = x.p
    while w is not T.nil:
        _update_additional_fields(T, w)
        w = w.p
    if y.color == Black:
        effective_os_delete_fixup(T, x)
    if p is not T.nil:
        p.succ = s
    if s is not T.nil:
        s.pred = p
    return y
Example #2
0
    def test_effective_os_tree(self):
        _, keys = get_random_array()
        tree = RedBlackTree(sentinel=OSNode(None))
        tree.nil.min = tree.nil.max = tree.nil.pred = tree.nil.succ = tree.nil

        for key in keys:
            effective_os_insert(tree, OSNode(key))

        nodes = get_binary_tree_nodes(tree, sentinel=tree.nil)

        while nodes:
            actual_minimum = effective_os_minimum(tree)
            actual_maximum = effective_os_maximum(tree)
            expected_minimum = rb_minimum(tree.root, sentinel=tree.nil)
            expected_maximum = rb_maximum(tree.root, sentinel=tree.nil)
            assert_that(actual_minimum, is_(expected_minimum))
            assert_that(actual_maximum, is_(expected_maximum))

            node = random.choice(nodes)
            actual_predecessor = effective_os_predecessor(tree, node)
            actual_successor = effective_os_successor(tree, node)
            expected_predecessor = rb_predecessor(node, sentinel=tree.nil)
            expected_successor = rb_successor(node, sentinel=tree.nil)
            assert_that(actual_predecessor, is_(expected_predecessor))
            assert_that(actual_successor, is_(expected_successor))

            effective_os_delete(tree, node)

            nodes = get_binary_tree_nodes(tree, sentinel=tree.nil)
Example #3
0
def os_delete(T, z):
    if z.left is T.nil or z.right is T.nil:
        y = z
    else:
        y = rb_successor(z, T.nil)
    if y.left is not T.nil:
        x = y.left
    else:
        x = y.right
    x.p = y.p
    if y.p is T.nil:
        T.root = x
    else:
        if y is y.p.left:
            y.p.left = x
        else:
            y.p.right = x
    if y is not z:
        z.key = y.key
        z.data = y.data
    w = x.p
    while w is not T.nil:
        w.size -= 1
        w = w.p
    if y.color == Black:
        os_delete_fixup(T, x)
    return y
Example #4
0
def _interval_pom_delete(T, z):
    if z.left is T.nil or z.right is T.nil:
        y = z
    else:
        y = rb_successor(z, sentinel=T.nil)
    if y.left is not T.nil:
        x = y.left
    else:
        x = y.right
    x.p = y.p
    if y.p is T.nil:
        T.root = x
    else:
        if y is y.p.left:
            y.p.left = x
        else:
            y.p.right = x
    if y is not z:
        z.key = y.key
        z.data = y.data
        z.low = y.low
        z.high = y.high
    w = x.p
    while w is not T.nil:
        _update_additional_fields(w)
        w = w.p
    if y.color == Black:
        _interval_pom_delete_fixup(T, x)
    return y
Example #5
0
def effective_os_insert(T, z):
    y = T.nil
    x = T.root
    while x is not T.nil:
        y = x
        if z.key < x.key:
            x = x.left
        else:
            x = x.right
    z.p = y
    if y is T.nil:
        T.root = z
    else:
        if z.key < y.key:
            y.left = z
        else:
            y.right = z
    z.left = z.right = T.nil
    z.color = Red
    z.size = 1
    z.min = z.max = z
    x = y
    while x is not T.nil:
        _update_additional_fields(T, x)
        x = x.p
    effective_os_insert_fixup(T, z)
    z.pred = rb_predecessor(z, sentinel=T.nil)
    if z.pred is not T.nil:
        z.pred.succ = z
    z.succ = rb_successor(z, sentinel=T.nil)
    if z.succ is not T.nil:
        z.succ.pred = z
Example #6
0
def joinable_rb_delete(T, z):
    if z.left is None or z.right is None:
        y = z
    else:
        y = rb_successor(z)
    if y.left is not None:
        x = y.left
    else:
        x = y.right
    if x is None:
        x = Node(None)  # create a dummy node that will mimic sentinel
    x.p = y.p
    if y.p is None:
        T.root = x
    else:
        if y is y.p.left:
            y.p.left = x
        else:
            y.p.right = x
    if y is not z:
        z.key = y.key
        z.data = y.data
    if y.color == Black:
        joinable_rb_delete_fixup(T, x)
    if x.key is None:  # if x is the dummy node replace it with None
        if x is T.root:
            T.root = None
            T.bh = 0
        else:
            if x is x.p.left:
                x.p.left = None
            else:
                x.p.right = None
    return y
Example #7
0
def min_gap_delete(Q, z):
    if z.left is Q.nil or z.right is Q.nil:
        y = z
    else:
        y = rb_successor(z, sentinel=Q.nil)
    if y.left is not Q.nil:
        x = y.left
    else:
        x = y.right
    x.p = y.p
    if y.p is Q.nil:
        Q.root = x
    else:
        if y is y.p.left:
            y.p.left = x
        else:
            y.p.right = x
    if y is not z:
        z.key = y.key
        z.data = y.data
    w = x.p
    while w is not Q.nil:
        _update_additional_fields(w)
        w = w.p
    if y.color == Black:
        min_gap_delete_fixup(Q, x)
    return y
Example #8
0
def joinable_rb_delete(T, z):
    if z.left is None or z.right is None:
        y = z
    else:
        y = rb_successor(z)
    if y.left is not None:
        x = y.left
    else:
        x = y.right
    if x is None:
        x = Node(None)  # create a dummy node that will mimic sentinel
    x.p = y.p
    if y.p is None:
        T.root = x
    else:
        if y is y.p.left:
            y.p.left = x
        else:
            y.p.right = x
    if y is not z:
        z.key = y.key
        z.data = y.data
    if y.color == Black:
        joinable_rb_delete_fixup(T, x)
    if x.key is None:  # if x is the dummy node replace it with None
        if x is T.root:
            T.root = None
            T.bh = 0
        else:
            if x is x.p.left:
                x.p.left = None
            else:
                x.p.right = None
    return y
Example #9
0
def rb_delete(T, z, sentinel=None):
    if z.left is sentinel or z.right is sentinel:
        y = z
    else:
        y = rb_successor(z, sentinel)
    if y.left is not sentinel:
        x = y.left
    else:
        x = y.right
    x.p = y.p
    if y.p is sentinel:
        T.root = x
    else:
        if y is y.p.left:
            y.p.left = x
        else:
            y.p.right = x
    if y is not z:
        z.key = y.key
        z.data = y.data
    if y.color == Black:
        rb_delete_fixup(T, x, sentinel)
    return y
Example #10
0
def persistent_rb_delete(T, z):
    T_ = RedBlackTree()
    T_.root = T_.nil = T.nil
    if z.left is T.nil or z.right is T.nil:
        y = z
    else:
        y = rb_successor(z, T.nil)
    path_length = _get_path_length_from_root_to_node(T, y)
    S = Array.indexed(1, path_length + 1)
    S.top = 0
    p = T.root
    r = T.nil
    p_ = r_ = T_.nil
    push(S, p_)
    z_ = T.nil
    while p is not y:
        p_ = rb.ParentlessNode.clone(p)
        push(S, p_)
        if p is z:
            z_ = p_
        if r_ is T_.nil:
            T_.root = p_
        else:
            if p is r_.left:
                r_.left = p_
            else:
                r_.right = p_
        r = p
        r_ = p_
        if y.key < p.key:
            p = p.left
        else:
            p = p.right
    if y.left is not T.nil:
        x = y.left
    else:
        x = y.right
    if y.color == Black:
        if x is not T.nil:
            x_ = rb.ParentlessNode.clone(x)
        else:
            x_ = T.nil
        if y is T.root:
            T_.root = x_
        else:
            if y is r.left:
                p_.left = x_
            else:
                p_.right = x_
        if y is not z:
            z_.key = y.key
            z_.data = y.data
        persistent_rb_delete_fixup(T_, S, x_)
    else:
        if y is r.left:
            p_.left = x
        else:
            p_.right = x
        if y is not z:
            z_.key = y.key
            z_.data = y.data
    return T_