def test_find_pom_tree(self): n = random.randint(1, 30) tree = RedBlackTree(sentinel=IntervalPomNode(None)) intervals = [] node_pairs = [] for _ in range(n): low_endpoint = random.randint(0, 899) high_endpoint = low_endpoint + random.randint(0, 100) interval = Interval(low_endpoint, high_endpoint) intervals.append(interval) node_pair = interval_pom_insert(tree, interval) node_pairs.append(node_pair) assert_interval_pom_tree(tree) while node_pairs: actual_pom = find_pom(tree) expected_poms = get_expected_poms(intervals) assert_that(actual_pom, is_in(expected_poms)) node_pair = random.choice(node_pairs) node_pairs.remove(node_pair) interval_to_delete = Interval(node_pair[0].key, node_pair[1].key) intervals.remove(interval_to_delete) interval_pom_delete(tree, *node_pair) assert_interval_pom_tree(tree)
def test_joinable_rb_insert(self): keys = [random.randrange(1000) for _ in range(20)] tree = RedBlackTree(sentinel=None) tree.bh = 0 for key in keys: joinable_rb_insert(tree, Node(key)) assert_red_black_tree(tree) assert_parent_pointers_consistent(tree) actual_keys = get_binary_tree_keys(tree) assert_that(actual_keys, contains_inanyorder(*keys)) actual_black_height = calculate_black_height(tree.root) assert_that(tree.bh, is_(equal_to(actual_black_height)))
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)
def test_min_gap_tree(self): _, keys = get_random_unique_array() tree = RedBlackTree() tree.nil.min_key = tree.nil.min_gap = math.inf tree.nil.max_key = -math.inf for key in keys: min_gap_insert(tree, Node(key)) nodes = get_binary_tree_nodes(tree, sentinel=tree.nil) while nodes: node = random.choice(nodes) key = node.key keys.remove(key) actual_found = min_gap_search(tree, key) assert_that(actual_found.key, is_(equal_to(key))) min_gap_delete(tree, node) actual_found = min_gap_search(tree, key) assert_that(actual_found, is_(tree.nil)) actual_min_gap = min_gap(tree) expected_min_gap = get_expected_min_gap(keys) assert_that(actual_min_gap, is_(equal_to(expected_min_gap))) nodes = get_binary_tree_nodes(tree, sentinel=tree.nil)
def os_count_inversions(A): n = A.length inversions = 0 tree = RedBlackTree(sentinel=OSNode(None)) for i in between(1, n): x = OSNode(A[i]) os_insert(tree, x) inversions += i - os_rank(tree, x) return inversions
def test_create_red_black_tree(self): left = Node(3) right = Node(20) root = Node(17, left=left, right=right) tree = RedBlackTree(root) assert_that(tree.root, is_(root)) assert_that(root.left, is_(left)) assert_that(root.right, is_(right)) assert_parent_pointers_consistent(tree, sentinel=tree.nil)
def josephus(n, m): T = RedBlackTree(sentinel=OSNode(None)) for j in between(1, n): x = OSNode(j) os_insert(T, x) j = 1 for k in rbetween(n, 1): j = (j + m - 1) % k + 1 x = os_select(T.root, j) print(x.key) os_delete(T, x)
def test_rb_parentless_insert(self): keys = [random.randrange(1000) for _ in range(20)] tree = RedBlackTree() for key in keys: parentless_rb_insert(tree, Node(key)) assert_red_black_tree(tree, sentinel=tree.nil) actual_keys = get_binary_tree_keys(tree, sentinel=tree.nil) assert_that(actual_keys, contains_inanyorder(*keys))
def test_persistent_rb_insert(self): keys = [random.randrange(1000) for _ in range(20)] tree = RedBlackTree() for i, key in enumerate(keys): new_tree = persistent_rb_insert(tree, ParentlessNode(key)) assert_red_black_tree(new_tree, sentinel=tree.nil) actual_keys_before_insertion = get_binary_tree_keys(tree, sentinel=tree.nil) actual_keys_after_insertion = get_binary_tree_keys(new_tree, sentinel=tree.nil) assert_that(actual_keys_before_insertion, contains_inanyorder(*keys[:i])) assert_that(actual_keys_after_insertion, contains_inanyorder(*keys[:i + 1])) tree = new_tree
def test_rb_insert(self): _, keys = get_random_array() tree = RedBlackTree() for key in keys: rb_insert(tree, Node(key), sentinel=tree.nil) assert_red_black_tree(tree, sentinel=tree.nil) assert_parent_pointers_consistent(tree, sentinel=tree.nil) actual_keys = get_binary_tree_keys(tree, sentinel=tree.nil) assert_that(actual_keys, contains_inanyorder(*keys))
def test_os_insert(self): keys = [random.randrange(1000) for _ in range(20)] tree = RedBlackTree(sentinel=OSNode(None)) for i, key in enumerate(keys): os_insert(tree, OSNode(key)) assert_os_tree(tree) assert_that(tree.root.size, is_(equal_to(i + 1))) assert_parent_pointers_consistent(tree, sentinel=tree.nil) actual_keys = get_binary_tree_keys(tree, sentinel=tree.nil) assert_that(actual_keys, contains_inanyorder(*keys))
def test_interval_insert(self): keys = [random.randrange(949) for _ in range(20)] tree = RedBlackTree(sentinel=IntervalNode(None, None)) for key in keys: interval_insert( tree, IntervalNode(key, Interval(key, key + random.randint(0, 50)))) assert_interval_tree(tree) assert_parent_pointers_consistent(tree, sentinel=tree.nil) actual_keys = get_binary_tree_keys(tree, sentinel=tree.nil) assert_that(actual_keys, contains_inanyorder(*keys))
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 get_random_red_black_tree(black_height=3, min_value=0, max_value=999, sentinel=rb.Node(None)): nodes = [] tree = RedBlackTree(get_random_red_black_subtree(black_height, nodes), sentinel=sentinel) tree_size = len(nodes) _, keys = get_random_unique_array(min_size=tree_size, max_size=tree_size, min_value=min_value, max_value=max_value) keys.sort() fill_subtree_with_keys(tree.root, keys, tree.nil) return tree, nodes, keys
def test_interval_search_exactly_positive(self): _, keys = get_random_array(max_size=100, max_value=89) tree = RedBlackTree(sentinel=IntervalNode(None, None)) intervals = [] for key in keys: i = Interval(key, key + random.randint(0, 10)) intervals.append(i) interval_insert_exactly(tree, IntervalNode(key, i)) assert_interval_tree(tree) interval = random.choice(intervals) actual_found = interval_search_exactly(tree, interval) assert_that(actual_found.int, is_(equal_to(interval)))
def intersecting_chords(C): n = C.length // 2 P = Array.indexed(1, n) for k in between(1, n): P[k] = 0 intersections = 0 T = RedBlackTree(sentinel=OSNode(None)) for k in between(1, 2 * n): j = C[k] if P[j] == 0: P[j] = k os_insert(T, OSNode(k)) else: x = os_search(T, P[j]) intersections = intersections + T.root.size - os_rank(T, x) os_delete(T, x) return intersections
def rectangles_overlap(A): T = RedBlackTree(sentinel=IntervalNode(None, None)) x_coords = [(rectangle[0].low, rectangle) for rectangle in A] + [(rectangle[0].high, rectangle) for rectangle in A] x_coords.sort(key=lambda p: p[0]) for p in x_coords: horizontal_side = p[1][0] vertical_side = p[1][1] if p[0] == horizontal_side.low: if interval_search(T, vertical_side) is not T.nil: return True interval_insert_exactly( T, IntervalNode(vertical_side.low, vertical_side)) else: v = interval_search_exactly(T, vertical_side) interval_delete(T, v) return False
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 activity_scheduler(s, f): n = s.length A = Array.indexed(1, n) F = Array(list(rbetween(n, 1))) F.top = n B = RedBlackTree() # events contains triples (a, b, c) where a = 0 if the event is finish of an activity and 1 if it is start, # b as the activity number, and c as the start time or the finish time events = [(0, i + 1, finish_time) for i, finish_time in enumerate(f)] + \ [(1, i + 1, start_time) for i, start_time in enumerate(s)] events.sort(key=lambda e: (e[2], e[0])) for e in events: if e[0] == 1: hall_number = pop(F) A[e[1]] = hall_number rb_insert(B, Node(e[1], data=hall_number), sentinel=B.nil) else: hall = rb_search(B.root, e[1], sentinel=B.nil) push(F, hall.data) rb_delete(B, hall, sentinel=B.nil) return A
def test_interval_search_exactly_random(self): _, keys = get_random_array(max_size=100, max_value=89) tree = RedBlackTree(sentinel=IntervalNode(None, None)) intervals = [] for key in keys: i = Interval(key, key + random.randint(0, 10)) intervals.append(i) interval_insert_exactly(tree, IntervalNode(key, i)) assert_interval_tree(tree) low_endpoint = random.randint(0, 89) high_endpoint = low_endpoint + random.randint(0, 10) interval = Interval(low_endpoint, high_endpoint) actual_found = interval_search_exactly(tree, interval) if actual_found is not tree.nil: assert_that(actual_found.int, is_(equal_to(interval))) else: for i in intervals: assert_that(interval, is_not(equal_to(i)))
def test_create_empty_red_black_tree(self): tree = RedBlackTree() assert_that(tree.root, is_(tree.nil)) assert_that(tree.nil.color, is_(Black))
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_
def setUp(self): self.tree = RedBlackTree()
class TestRedBlackTree(unittest.TestCase): def setUp(self): self.tree = RedBlackTree() def test_empty(self): self.assertTrue(self.tree.empty()) def test_get_inorder(self): self.assertListEqual([], self.tree.get_inorder()) self.tree.insert(3) self.tree.insert(1) self.tree.insert(5) self.assertListEqual([(1, NodeColor.RED), (3, NodeColor.BLACK), (5, NodeColor.RED)], self.tree.get_inorder()) def test_print_inorder(self): self.assertEqual("", self.tree.print_inorder()) self.tree.insert(3) self.tree.insert(1) self.tree.insert(5) self.assertEqual("1R, 3B, 5R", self.tree.print_inorder()) def test_insert(self): self.tree.insert([10, 20, 30]) self.assertListEqual([(10, NodeColor.RED), (20, NodeColor.BLACK), (30, NodeColor.RED)], self.tree.get_inorder()) self.tree.insert(15) self.assertListEqual([(10, NodeColor.BLACK), (15, NodeColor.RED), (20, NodeColor.BLACK), (30, NodeColor.BLACK)], self.tree.get_inorder()) def test_max(self): self.tree.insert([10, 20, 56, 78]) self.assertListEqual([(10, NodeColor.BLACK), (20, NodeColor.BLACK), (56, NodeColor.BLACK), (78, NodeColor.RED)], self.tree.get_inorder()) self.assertEqual(self.tree.max(), 78) def test_min(self): self.tree.insert([0, 20, 1, 5]) self.assertListEqual([(0, NodeColor.BLACK), (1, NodeColor.BLACK), (5, NodeColor.RED), (20, NodeColor.BLACK)], self.tree.get_inorder()) self.assertEqual(self.tree.min(), 0) def test_find(self): self.tree.insert([3, 1, 0, 5]) self.assertTrue(self.tree.find(0)) self.assertTrue(self.tree.find(5)) self.assertFalse(self.tree.find(10)) def test_contains(self): self.assertFalse(0 in self.tree) self.tree.insert([4, 5, 0, 2]) self.assertFalse(10 in self.tree) self.assertTrue(0 in self.tree)
def test_create_empty_red_black_tree_without_sentinel(self): tree = RedBlackTree(sentinel=None) assert_that(tree.root, is_(none())) assert_that(tree.nil, is_(none()))