def sorted_arr_to_bst(arr: list) -> Node:
    """
    time complexity: O(n)
    space complexity: O(n)  # array and stack
    """

    def construct_bst(elements) -> Optional[Node]:
        length = len(elements)

        if length <= 0:
            return None

        if length == 1:
            return Node(elements[0])

        root_position = int(length / 2)
        root = Node(elements[root_position])
        root.left = construct_bst(elements[:root_position])
        root.right = construct_bst(elements[root_position + 1 :])
        return root

    return construct_bst(arr)


if __name__ == "__main__":
    from random import randint

    for _ in range(5):
        inorder(sorted_arr_to_bst(list(range(randint(2, 20)))))
        print()
Beispiel #2
0
    Fact: Number of nodes in left and right half should be roughly n/2
    Time complexity: O(n)
    Space complexity: O(n)  # stack
    """
    def balanced_bst(n: int) -> Optional[Node]:
        """
        This implementation constructs the tree in bottom up fashion.
        In case it's sorted array, part arrays could be sent to balanced_bst
        recursive function to create the tree, still in bottom up fashion
        """
        nonlocal index

        if n <= 0:
            return None

        left_nodes = int(n / 2)
        left = balanced_bst(left_nodes)
        node = Node(linked_list[index])
        node.left = left
        index += 1
        node.right = balanced_bst(n - left_nodes - 1)
        return node

    length: int = len(linked_list)
    index: int = 0
    return balanced_bst(length)


if __name__ == "__main__":
    print(inorder(create_balanced_bst([1, 2, 3, 4, 5, 6, 7])))
Beispiel #3
0
    space complexity: O(n)
    """
    def construct(node: Optional[Node]) -> Optional[Node]:
        """
        Reverse inorder traversal
        """
        nonlocal total

        if node:
            construct(node.right)
            node.data, total = total, total + node.data
            construct(node.left)

        return node

    total: int = 0
    return construct(root_node)


if __name__ == "__main__":
    root = Node(11)
    root.left = Node(2)
    root.left.left = Node(1)
    root.left.right = Node(7)
    root.right = Node(29)
    root.right.left = Node(15)
    root.right.right = Node(40)
    root.right.right.left = Node(35)

    inorder(greater_sum_bst(root))
    space complexity: O(n)
    """
    def construct_tree(min_: int, max_: int) -> Optional[Node]:
        nonlocal pre_index
        nonlocal l

        if pre_index >= l:
            return None

        value = preorder[pre_index]

        if min_ < value < max_:
            node = Node(value)
            pre_index += 1

            node.left = construct_tree(min_, value)
            node.right = construct_tree(value, max_)

            return node

        return None

    pre_index: int = 0
    l: int = len(preorder)
    return construct_tree(-1_000_000, 1_000_000)


if __name__ == "__main__":
    print(inorder(get_bst([10, 5, 1, 7, 40, 50])))
    print(inorder(get_bst_using_min_and_max_value([10, 5, 1, 7, 40, 50])))
def construct_bst(preorder: array,
                  start: Optional[int] = None,
                  end: Optional[int] = None) -> Optional[Node]:
    """
    BST: left - smaller than current
         right - bigger than current
    """
    if start is None:
        start = 0
    if end is None:
        end = len(preorder) - 1
    if start > end:
        return None

    node = Node(preorder[start])

    if start < end:
        index = start + 1

        while index < end and preorder[index] < preorder[start]:
            index += 1

        node.left = construct_bst(preorder, start + 1, index - 1)
        node.right = construct_bst(preorder, index, end)

    return node


if __name__ == "__main__":
    inorder(construct_bst(array("I", [10, 5, 1, 7, 40, 50])))