예제 #1
0
    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)
예제 #2
0
    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)))
예제 #3
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)
예제 #4
0
    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)
예제 #5
0
    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)))
예제 #6
0
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
예제 #7
0
    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)
예제 #8
0
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)
예제 #9
0
    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))
예제 #10
0
    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
예제 #11
0
    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))
예제 #12
0
    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))
예제 #13
0
    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))
예제 #14
0
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_
예제 #15
0
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
예제 #16
0
    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)))
예제 #17
0
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
예제 #18
0
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
예제 #19
0
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
예제 #20
0
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
예제 #21
0
    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)))
예제 #22
0
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
예제 #23
0
    def test_create_empty_red_black_tree(self):
        tree = RedBlackTree()

        assert_that(tree.root, is_(tree.nil))
        assert_that(tree.nil.color, is_(Black))
예제 #24
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_
 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)
예제 #27
0
    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()))