示例#1
0
def test_get_next__successor_complex():
    A = BinaryNode(1)
    C = BinaryNode(3)
    B = BinaryNode(2, left=A, right=C)
    D = BinaryNode(4, left=B, right=None)
    assert get_next(A).value == 2
    assert get_next(B).value == 3
    assert get_next(C).value == 4
    assert get_next(D) is None
def test_find__something_in_the_middle():
    root = BinaryNode(5)
    root.left = BinaryNode(3)
    root.right = BinaryNode(7)
    root.left.left = BinaryNode(2)
    root.left.right = BinaryNode(4)
    root.right.left = BinaryNode(6)
    root.right.right = BinaryNode(8)
    assert find(root.left.left, root.left.right) == root.left
示例#3
0
def to_bst(array):
    """
    One way to approach this problem is to pick the middle value, and then
    recursively build the BST from the root down by picking middle values for
    the left and the right of the root.  This can be a bit tedious by having to
    perform index arithmetic, and I hate index arithmetic.

    One thing that is nice about the question is that we are given a total
    ordering, so this means that for any element in the array, we have a
    guarantee that the previous element is less than, and the next element is
    greater than, strictly.

    This allows us to build the BST in layers, like a cake.  In the first pass,
    every other element in the array is taken and these become the leaf nodes
    of our BST.  They are added to an "orphans" queue.  In the next pass, we
    take every other element again, only this time, it checks the orphans queue
    to assign left and right nodes.

    I think the runtime is something like O(log^2 n) because we make at most
    log n passes over the number of elements, but each time, we are only
    working with half the number of elements from the previous step.
    """
    @dataclass
    class MarkedElement:
        value: object
        marked: bool = False

    elements = [MarkedElement(value=v) for v in array]
    orphans = deque([])

    def unmarked(elements):
        return list(filter(lambda e: not e.marked, elements))

    parents = deque([])
    while len(unmarked(elements)) > 0:
        for index, element in enumerate(unmarked(elements)):
            if index % 2 == 0:
                element.marked = True
                parent = BinaryNode(element.value,
                                    left=safe_popleft(orphans),
                                    right=safe_popleft(orphans))
                parents.append(parent)

        parents.reverse()
        orphans.extendleft(parents)
        parents.clear()

    # the final orphan is the root of the tree
    root = safe_popleft(orphans)
    return root
示例#4
0
def test_check__none_cannot_have_subtrees():
    assert not check(None, BinaryNode(1))
示例#5
0
def test_check__none_is_subtree():
    assert check(BinaryNode(1), None)
示例#6
0
def test_check__complex_subtree():
    tree = BinaryNode(5)
    tree.left = BinaryNode(3)
    tree.right = BinaryNode(7)
    tree.left.left = BinaryNode(2)
    tree.left.right = BinaryNode(4)
    tree.right.left = BinaryNode(6)
    tree.right.right = BinaryNode(8)

    assert check(tree, BinaryNode(7, left=BinaryNode(6), right=BinaryNode(8)))
示例#7
0
def test_check__against_self():
    tree = BinaryNode(2, left=BinaryNode(1), right=BinaryNode(3))
    assert check(tree, tree)
示例#8
0
def test_check__single_node_subtree():
    tree = BinaryNode(2, left=BinaryNode(1), right=BinaryNode(3))
    assert check(tree, BinaryNode(1))
    assert check(tree, BinaryNode(3))
示例#9
0
def test_get_next__no_successor_self_is_at_root():
    assert get_next(BinaryNode(1)) is None
示例#10
0
def test_get_next__parent_is_successor():
    node = BinaryNode(2, left=BinaryNode(1))
    assert get_next(node.left).value == 2
示例#11
0
def test_get_next__simple_successor():
    node = BinaryNode(1, right=BinaryNode(2))
    assert get_next(node).value == 2
示例#12
0
def test_is_bst__not_at_all():
    root = BinaryNode(7, left=BinaryNode(9), right=BinaryNode(1))
    assert not is_bst(root)
示例#13
0
def test_is_bst__simple():
    root = BinaryNode(2, left=BinaryNode(1), right=None)
    assert is_bst(root)
示例#14
0
def test_is_bst__one():
    assert is_bst(BinaryNode(1))
示例#15
0
def test_find__only_the_root():
    root = BinaryNode(1)
    assert find(root, root) == root
示例#16
0
def test_find__it_is_the_root():
    left = BinaryNode(1)
    right = BinaryNode(9)
    root = BinaryNode(5, left=left, right=right)
    assert find(left, right) == root