def rb_join(T1, x, T2): T = RedBlackTree(sentinel=None) if T1.bh >= T2.bh: if T2.root is None: joinable_rb_insert(T1, x) return T1 T.root = x T.bh = T1.bh y = rb_join_point(T1, T2) x.left = y x.right = T2.root if y is not T1.root: if y is y.p.left: y.p.left = x else: y.p.right = x T.root = T1.root x.p = y.p T2.root.p = y.p = x else: if T1.root is None: joinable_rb_insert(T2, x) return T2 T.root = x T.bh = T2.bh y = rb_symmetric_join_point(T1, T2) x.right = y x.left = T1.root if y is not T2.root: if y is y.p.right: y.p.right = x else: y.p.left = x T.root = T2.root x.p = y.p T1.root.p = y.p = x x.color = Red joinable_rb_insert_fixup(T, x) return T
def persistent_rb_insert(T, z): path_length = _get_path_length_from_root_to_node(T, z) S = Array.indexed(1, path_length + 1) S.top = 0 y = T.nil x = T.root T_ = RedBlackTree(sentinel=T.nil) y_ = T_.nil push(S, y_) while x is not T.nil: y = x x_ = rb.ParentlessNode.clone(x) if y_ is T_.nil: T_.root = x_ else: if x is y_.left: y_.left = x_ else: y_.right = x_ y_ = x_ push(S, y_) if z.key < x.key: x = x.left else: x = x.right 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 _persistent_rb_insert_fixup(T_, S, z) return T_
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_