def build_min_height_bst_from_sorted_subarray(start, end):
     if start >= end:
         return None
     mid = (start + end) // 2
     return BstNode(A[mid],
                    build_min_height_bst_from_sorted_subarray(start, mid),
                    build_min_height_bst_from_sorted_subarray(mid + 1, end))
Esempio n. 2
0
def build_min_height_bst_from_sorted_array(A: List[int]) -> Optional[BstNode]:
    if not A:
        return None
    return BstNode(
        A[len(A) // 2],
        left=build_min_height_bst_from_sorted_array(A[:len(A) // 2]),
        right=build_min_height_bst_from_sorted_array(A[len(A) // 2 + 1:]))
 def build_tree(l: int, r: int) -> Optional[BstNode]:
     if r < l: return None
     m = (l + r) // 2
     root: BstNode = BstNode(A[m])
     root.left = build_tree(l, m - 1)
     root.right = build_tree(m + 1, r)
     return root
Esempio n. 4
0
    def build_tree(start, end):
        if start > end:
            return None

        root_val = preorder_sequence[start]

        right_index = start + 1
        while right_index <= end:
            if preorder_sequence[right_index] > root_val:
                break
            right_index += 1

        tree = BstNode(root_val)
        tree.left = build_tree(start + 1, right_index - 1)
        tree.right = build_tree(right_index, end)

        return tree
def build_min_height_bst_from_sorted_array(A):
    if len(A) == 0:
        return None

    n = len(A)
    return BstNode(A[n // 2],
                   build_min_height_bst_from_sorted_array(A[:n // 2]),
                   build_min_height_bst_from_sorted_array(A[n // 2 + 1:]))
Esempio n. 6
0
    def build_bst(start=0, end=len(A)-1):
        if start > end:
            return None

        m = (start + end) // 2

        left = build_bst(start, m - 1)
        right = build_bst(m + 1, end)

        return BstNode(A[m], left, right)
def build_min_height_bst_from_sorted_array(A):
    # SOS!!! check exactly the limits of the subarrays!
    if not A:
        return None

    head_idx = len(A) // 2

    return BstNode(A[head_idx],
                   build_min_height_bst_from_sorted_array(A[:head_idx]),
                   build_min_height_bst_from_sorted_array(A[head_idx + 1:]))
Esempio n. 8
0
 def make(lower_bound, upper_bound):
     if index[0] == len(preorder_sequence):
         return None
     root = preorder_sequence[index[0]]
     if not lower_bound <= root <= upper_bound:
         return None
     index[0] += 1
     L = make(lower_bound, root)
     R = make(root, upper_bound)
     return BstNode(root, L, R)
def rebuild_bst_from_preorder(preorder_sequence):
    if not preorder_sequence:
        return None
    
    point = next((i for i, val in enumerate(preorder_sequence)
                  if val > preorder_sequence[0]),
                  len(preorder_sequence))

    return BstNode(preorder_sequence[0],
                   rebuild_bst_from_preorder(preorder_sequence[1:point]),
                   rebuild_bst_from_preorder(preorder_sequence[point:]))
Esempio n. 10
0
def rebuild_bst_from_preorder(preorder_sequence):
    if not preorder_sequence:
        return None

    transition_point = next((i for i, a in enumerate(preorder_sequence)
                             if a > preorder_sequence[0]),
                            len(preorder_sequence))
    return BstNode(
        preorder_sequence[0],
        rebuild_bst_from_preorder(preorder_sequence[1:transition_point]),
        rebuild_bst_from_preorder(preorder_sequence[transition_point:]))
def build_min_height_bst_from_sorted_array(A: List[int]) -> Optional[BstNode]:
    if len(A) == 0:
        return None

    root_idx = len(A) // 2
    root = A[root_idx]
    left_list = A[:root_idx]
    right_list = A[root_idx + 1:]
    left_subtree = build_min_height_bst_from_sorted_array(left_list)
    right_subtree = build_min_height_bst_from_sorted_array(right_list)
    return BstNode(root, left_subtree, right_subtree)
Esempio n. 12
0
 def helper(root_idx, lower_bound, upper_bound):
     if root_idx >= len(preorder_sequence):
         return None
     elif not lower_bound <= preorder_sequence[root_idx] <= upper_bound:
         return None
     root = preorder_sequence[root_idx]
     root_idx += 1
     return BstNode(
         root,
         helper(root_idx, lower_bound, root),
         helper(root_idx, root, upper_bound),
     )
Esempio n. 13
0
def rebuild_bst_from_preorder(
        preorder_sequence: List[int]) -> Optional[BstNode]:
    if len(preorder_sequence) == 0: return None
    root = BstNode(preorder_sequence[0])
    searchPath = deque([root], maxlen=len(preorder_sequence))
    i = 1
    while i < len(preorder_sequence):
        if preorder_sequence[i] < preorder_sequence[i - 1]:
            node = BstNode(preorder_sequence[i])
            searchPath[-1].left = node
            searchPath.append(node)
        else:
            node = searchPath.pop()
            while len(
                    searchPath) and searchPath[-1].data < preorder_sequence[i]:
                node = searchPath.pop()
            right = BstNode(preorder_sequence[i])
            node.right = right
            searchPath.append(right)
        i += 1
    return root
def binary_tree_from_preorder_inorder(preorder, inorder):
    # for a preorder traversal, the first element is the root,
    # followed by a set of elements for the left subtree then the right
    # the set of left subtree elements in the preorder traversal can be determined by
    # using the root element to divide the inorder traversal elements into
    # left and right subtree elements,
    # the left subtree elements in the inorder traversal is the elements that
    # preceeds the root element in the inorder traversal
    if not preorder:
        return None
    root_val = preorder[0]
    root = BstNode(root_val)
    inorder_root_index = inorder.index(root_val)
    inorder_left_tree = inorder[:inorder_root_index]
    inorder_right_tree = inorder[inorder_root_index + 1:]
    preorder_left_tree = preorder[1:(len(inorder_left_tree) + 1)]  #skip root
    preorder_right_tree = preorder[(len(inorder_left_tree) + 1):]
    root.left = binary_tree_from_preorder_inorder(preorder_left_tree,
                                                  inorder_left_tree)
    root.right = binary_tree_from_preorder_inorder(preorder_right_tree,
                                                   inorder_right_tree)
    return root
    def rebuild_bst_from_preorder_on_value_range(lower_bound, upper_bound):
        if root_idx[0] == len(preorder_sequence):
            return None

        root = preorder_sequence[root_idx[0]]
        if not lower_bound <= root <= upper_bound:
            return None

        root_idx[0] += 1
        left_subtree = rebuild_bst_from_preorder_on_value_range(
            lower_bound, root)
        right_subtree = rebuild_bst_from_preorder_on_value_range(
            root, upper_bound)

        return BstNode(root, left_subtree, right_subtree)
Esempio n. 16
0
    def rebuild_bst_from_preorder_on_value_range(lower_bound, upper_bound):
        if root_idx[0] == len(preorder_sequence):
            return None

        root = preorder_sequence[root_idx[0]]
        if not lower_bound <= root <= upper_bound:
            return None
        root_idx[0] += 1
        # Note that rebuild_bst_from_preorder_on_value_range updates root_idx[0]
        # So the order of following two calls are critical
        left_subtree = rebuild_bst_from_preorder_on_value_range(
            lower_bound, root)
        right_subtree = rebuild_bst_from_preorder_on_value_range(
            root, upper_bound)
        return BstNode(root, left_subtree, right_subtree)
Esempio n. 17
0
    def reconstruct(lower_bound, upper_bound):
        if root_idx[0] == len(preorder_sequence):
            return None

        root = preorder_sequence[root_idx[0]]

        if not (lower_bound < root < upper_bound):
            return None

        root_idx[0] += 1

        left_subtree = reconstruct(lower_bound, root)
        right_subtree = reconstruct(root, upper_bound)

        return BstNode(root, left_subtree, right_subtree)
Esempio n. 18
0
    def reconstruct(preorder_start, preorder_end):
        if preorder_start > preorder_end:
            return None

        root = preorder_sequence[preorder_start]

        # Find idx where val > root
        partition_idx = preorder_start
        for i in range(preorder_start + 1, preorder_end + 1):
            if preorder_sequence[i] < root:
                partition_idx = i
            else:
                break

        return BstNode(root, reconstruct(preorder_start + 1, partition_idx),
                       reconstruct(partition_idx + 1, preorder_end))
Esempio n. 19
0
def merge_two_sorted_lists(A, B):
    sorted_head = BstNode()
    tail = sorted_head

    AB = [A, B]
    while all(AB):
        A_or_B = 0 if AB[0].data < AB[1].data else 1
        tail.right = AB[A_or_B]
        tail = tail.right  # Resets tail to the last node.
        AB[A_or_B] = tail.right

    if AB[0]:  # Appends the remaining of A.
        tail.right = AB[0]
    elif AB[1]:  # Appends the remaining of B.
        tail.right = AB[1]
    return sorted_head.right
Esempio n. 20
0
    def build_bst(lower_bound=-float('inf'), upper_bound=+float('inf')):
        nonlocal root_idx

        if root_idx >= len(preorder_sequence):
            return None

        root = preorder_sequence[root_idx]
        if not lower_bound < root < upper_bound:
            return None

        root_idx += 1

        left = build_bst(lower_bound, root)
        right = build_bst(root, upper_bound)

        return BstNode(root, left, right)
def find_k_largest_in_bst(tree: BstNode, k: int) -> List[int]:
    #Reverse inorder traversal (sorta)
    path = []
    stack = [tree]
    while k != 0 and stack:
        tree = stack.pop()
        if tree:
            if tree.left:
                stack.append(tree.left)
            if not tree.right:
                #Current node is the right most value
                path.append(tree.data)
                k -= 1
            else:
                #Keeping going right, but save the current node too
                right = tree.right
                tree.left, tree.right = None, None  #Prune the tree
                stack.append(tree)
                stack.append(right)

    return path
Esempio n. 22
0
from test_framework import generic_test
from bst_node import BstNode

left_left = BstNode(4)
left_right = BstNode(5)
left = BstNode(1, left_left, left_right)
right = BstNode(3)
root = BstNode(2, left, right)
print('root={}, left={}, right={}'.format(root, left, right))
root_parent_l = BstNode(6, root)
root_parent_l_parent_l = BstNode(7, root_parent_l)

result = []


def tree_traversal(tree, result, order):
    # TODO - you fill in here.
    if tree:
        if order == -1:
            print('Preorder: {}'.format(tree.data))
            result.append(tree.data)
        tree_traversal(tree.left, result, order)
        if order == 0:
            print('Inorder: {}'.format(tree.data))
            result.append(tree.data)
        tree_traversal(tree.right, result, order)
        if order == 1:
            print('Postorder: {}'.format(tree.data))
            result.append(tree.data)
    print('tree={}, result={}'.format(tree, result))
    return result
from test_framework import generic_test

from bst_node import BstNode
# preorder = [1,2,3], inorder=[2,1,3], ["1", "2", "3"]
# preorder = [1, 2, 3, 4]	inorder = [4, 3, 2, 1]	["1", "2", "null", "3", "null", "4"]

# preorder = ['H','B','F','E','A','C','D','G','I']
# inorder = ['F','B','A','E','H','C','D','I','G']
pl = ['B', 'F', 'E', 'A']
il = ['F', 'B', 'A', 'E']
pr = ['C', 'D', 'G', 'I']
ir = ['C', 'D', 'I', 'G']
# left subtree
a = BstNode('A')
e = BstNode('E', a)
f = BstNode('F')
b = BstNode('B', f, e)
# right subtree
i = BstNode('I')
g = BstNode('G', i)
d = BstNode('D', None, g)
c = BstNode('C', None, d)
h = BstNode('H', b, c)


def x_binary_tree_from_preorder_inorder(preorder, inorder):
    def reconstruct_tree(preorder, inorder):
        # TODO - you fill in here.
        # 1. root is first node in preorder traversal
        # 2. use root to divide inorder traversal into left and right subtrees (inorder)
        # 3. use (left,right) inorder traversal set to partition preorder traversal
Esempio n. 24
0
 def getRoot(A, low, high):
     if low > high:
         return None
     mid = low + ((high - low) // 2)
     return BstNode(A[mid], getRoot(A, low, mid - 1), getRoot(A, mid + 1, high))
Esempio n. 25
0
from test_framework import generic_test
from bst_node import BstNode

left_left = BstNode(2)
left_right = BstNode(4)
left = BstNode(3, left_left, left_right)
right = BstNode(6)
root = BstNode(5, left, right)
print('root={}, left={}, right={}'.format(root, left, right))


def tree_traversal(tree, order, result):
    # TODO - you fill in here.
    # print('tree_traversal,tree={},result={},order={}'.format(tree, result, order))
    if tree:
        if order == -1:
            # print('Preorder: {}'.format(tree.data))
            result.append(tree.data)
        tree_traversal(tree.left, order, result)
        if order == 0:
            # print('Inorder: {}'.format(tree.data))
            result.append(tree.data)
        tree_traversal(tree.right, order, result)
        if order == 1:
            # print('Postorder: {}'.format(tree.data))
            result.append(tree.data)
    # print('result={}'.format(result))
    return result


def preorder_traversal(tree):
Esempio n. 26
0
 def helper(i, j):
     if i < j:
         m = (j + i) // 2
         return BstNode(A[m], helper(i, m), helper(m + 1, j))