예제 #1
0
def convert_sorted_array_to_bst(array, l, h):
    if l > h:
        return None

    mid = (l + h) // 2

    root = Node(array[mid])

    root.left = convert_sorted_array_to_bst(array, l, mid - 1)
    root.right = convert_sorted_array_to_bst(array, mid + 1, h)

    return root
def convert(preorder, inorder, start, end):
    global pre_index
    if start > end:
        return None

    root_val = preorder[pre_index]
    pre_index += 1
    root = Node(root_val)
    in_index = search(root_val, inorder, start, end)

    root.left = convert(preorder, inorder, start, in_index - 1)
    root.right = convert(preorder, inorder, in_index + 1, end)

    return root
def tree_from_ancestor_matrix(matrix):
    nodes = [Node(i) for i in range(len(matrix))]
    used = [False for i in range(len(matrix))]
    level_map = create_level_map(matrix)

    root = nodes[level_map[0][0]]

    for level in sorted(level_map.keys()):

        for node in level_map[level]:

            next_level_nodes = level_map.get(level + 1, [])

            for child in next_level_nodes:
                if used[child]:
                    continue

                # if node is ancestor of child, then node is parent
                parent_node = nodes[node]
                child_node = nodes[child]

                if parent_node.left is None:
                    parent_node.left = child_node
                    used[child] = True
                elif parent_node.right is None:
                    parent_node.right = child_node
                    used[child] = True

    return root
예제 #4
0
def create_tree(post_order, _min, _max):
    global POST_INDEX
    if POST_INDEX < 0:
        return None

    root = None

    key = post_order[POST_INDEX]
    if _min < key < _max:
        root = Node(key)
        POST_INDEX -= 1

        root.right = create_tree(post_order, key, _max)
        root.left = create_tree(post_order, _min, key)

    return root
예제 #5
0
def create_tree(pre, pre_ln):
    global index

    if index >= len(pre):
        return None

    root = Node(pre[index])

    if pre_ln[index] == 'L':
        index += 1
        return root

    index += 1
    root.left = create_tree(pre, pre_ln)
    root.right = create_tree(pre, pre_ln)

    return root
예제 #6
0
def construct_tree(pre, post, start, end, N):
    global PRE_INDEX

    if PRE_INDEX >= N or start > end:
        return None

    root = Node(pre[PRE_INDEX])
    PRE_INDEX += 1

    if start == end:
        return root

    index = search(post, pre[PRE_INDEX], start, end)

    if index <= end:
        root.left = construct_tree(pre, post, start, index, N)
        root.right = construct_tree(pre, post, index + 1, end, N)

    return root
예제 #7
0
def create_bst(pre_order, _min, _max):
    global PRE_INDEX

    if PRE_INDEX >= len(pre_order):
        return None

    root = None

    data = pre_order[PRE_INDEX]

    if _min < data < _max:
        root = Node(data)
        PRE_INDEX += 1

        root.left = create_bst(pre_order, _min, data)

        root.right = create_bst(pre_order, data, _max)

    return root
예제 #8
0
def build_tree(arr, start, end):
    if start > end:
        return

    root_index = find_max_index(arr, start, end)
    root = Node(arr[root_index])

    root.left = build_tree(arr, start, root_index - 1)
    root.right = build_tree(arr, root_index + 1, end)

    return root


# r = build_tree([1, 5, 10, 40, 30, 15, 28, 20], 0, 7)
# print r
# print r.left
# print r.right
# print r.left.left
# print r.right.right
# print r.left.left.left
# print r.right.right.left
# print r.right.right.right
def get_all_trees(arr, start, end):
    if start > end:
        return [None]

    trees = []

    for i in range(start, end + 1):
        l_trees = get_all_trees(arr, start, i - 1)

        r_trees = get_all_trees(arr, i + 1, end)

        for j in l_trees:
            for k in r_trees:

                node = Node(arr[i])

                node.left = j
                node.right = k

                trees.append(node)

    return trees
예제 #10
0
def get_tree_from_parent_array(array):
    root = None
    nodes = [Node(i) for i in range(len(array))]

    for i in range(len(array)):
        node = nodes[i]
        parent_index = array[i]
        if parent_index != -1:
            parent = nodes[parent_index]
            make_child(node, parent)
        else:
            root = node

    return root
예제 #11
0
    if root == node:
        print_child_nodes_at_dist_k(root, k)
        return 1

    left_dist = print_at_dist_k(root.left, node, k)
    right_dist = print_at_dist_k(root.right, node, k)

    if left_dist > 0:
        print_child_nodes_at_dist_k(root.right, k - (left_dist + 1))
        return left_dist + 1

    if right_dist > 0:
        print_child_nodes_at_dist_k(root.left, k - (right_dist + 1))
        return right_dist + 1

    return -1


if __name__ == '__main__':
    r = Node(1)
    r.left = Node(2)
    r.right = Node(3)
    r.left.left = Node(4)
    r.left.right = Node(5)
    r.right.left = Node(6)
    r.right.right = Node(7)
    r.left.right.right = Node(8)
    r.left.right.right.left = Node(9)

    print_at_dist_k(r, r.left, 3)
예제 #12
0
"""
from G4G.Problems.bst.vertical_sum import Node


def populate_element_sizes(root, elements_at_levels, level):
    if root:
        elements_at_levels[level] += 1

        populate_element_sizes(root.left, elements_at_levels, level + 1)
        populate_element_sizes(root.right, elements_at_levels, level + 1)


def max_width(root):
    elements_at_levels = [0 for i in range(4)]  # should be range(height)
    populate_element_sizes(root, elements_at_levels, 0)

    return max(elements_at_levels)


if __name__ == '__main__':
    root = Node(1)
    root.left = Node(2)
    root.right = Node(3)
    root.left.left = Node(4)
    root.left.right = Node(5)
    root.right.right = Node(8)
    root.right.right.left = Node(6)
    root.right.right.right = Node(7)

    print max_width(root)
예제 #13
0
def get_test_tree():
    root = Node('a')

    root.left = Node('b')
    root.right = Node('c')

    root.left.left = Node('d')
    root.left.right = Node('e')
    root.right.left = Node('f')
    root.right.right = Node('g')

    root.left.left.left = Node('h')
    root.left.left.right = Node('i')
    root.left.right.left = Node('j')
    root.left.right.right = Node('k')
    root.right.left.left = Node('l')
    root.right.left.right = Node('m')
    root.right.right.left = Node('n')
    root.right.right.right = Node('o')

    return root
예제 #14
0
    if is_leaf(root):
        return root.data

    left_sum = max_leaf_to_root_paths(root.left)
    right_sum = max_leaf_to_root_paths(root.right)

    curr_sum = left_sum + right_sum + root.data
    if curr_sum > MAX_SUM:
        MAX_SUM = curr_sum

    return max(left_sum, right_sum) + root.data


if __name__ == '__main__':
    r = Node(-15)
    r.left = Node(5)
    r.right = Node(6)
    r.left.left = Node(-8)
    r.left.right = Node(-1)
    r.left.left.left = Node(2)
    r.left.left.right = Node(6)
    r.right.left = Node(3)
    r.right.right = Node(9)
    r.right.right.right = Node(0)
    r.right.right.right.left = Node(4)
    r.right.right.right.right = Node(-1)
    r.right.right.right.right.left = Node(10)

    max_leaf_to_root_paths(r)
    print MAX_SUM
        return node.left.right == node

    return node.left.right == node and node.right.left == node


def height(root):
    if root is None:
        return 0

    if is_dll_leaf(root):
        return 1

    return 1 + max(height(root.left), height(root.right))


if __name__ == '__main__':
    r = Node(1)
    r.left = Node(2)
    r.right = Node(3)
    r.left.left = Node(4)
    r.left.right = Node(5)
    r.left.left.left = Node(6)

    r.left.left.left.right = r.left.right
    r.left.right.left = r.left.left.left

    r.left.right.right = r.right
    r.right.left = r.left.right

    print height(r)
예제 #16
0
    node.left = l_node
    return node


def double_tree(root):
    if root is None:
        return None

    root.left = double_tree(root.left)
    root.right = double_tree(root.right)

    return double_node(root)


if __name__ == '__main__':
    root = Node(1)
    root.left = Node(2)
    root.right = Node(3)

    double_tree(root)

    print get_inorder_array(root, [])

    root = Node(1)
    root.left = Node(2)
    root.right = Node(3)
    root.left.left = Node(4)
    root.left.right = Node(5)

    double_tree(root)
예제 #17
0
                    curr2 = s2.pop()
                    val2 = curr2.data
                    curr2 = curr2.left
                    done2 = True

        # val1 != val2 makes sure that two of same values are not added
        if val1 != val2 and val1 + val2 == target:
            print 'pair found: {0} and {1}'.format(val1, val2)
            return True

        elif val1 + val2 < target:
            done1 = False

        elif val1 + val2 > target:
            done2 = False

        if val2 <= val1:
            return False


if __name__ == '__main__':
    r = Node(15)
    r.left = Node(10)
    r.right = Node(20)
    r.left.left = Node(8)
    r.left.right = Node(12)
    r.right.left = Node(16)
    r.right.right = Node(25)

    print is_sum_pair_present(r, 33)
예제 #18
0
CURR_VAL = 0


def add_greater_vals(root):
    global CURR_VAL

    if root is None:
        return

    add_greater_vals(root.right)

    root.data += CURR_VAL
    CURR_VAL = root.data

    add_greater_vals(root.left)


if __name__ == '__main__':
    r = Node(50)
    r.left = Node(30)
    r.right = Node(70)
    r.left.left = Node(20)
    r.left.right = Node(40)
    r.right.left = Node(60)
    r.right.right = Node(80)

    add_greater_vals(r)

    print get_inorder_array(r, [])
예제 #19
0
def get_node(array, index):
    if index >= len(array):
        return None

    return Node(array[index])
예제 #20
0
    sum_left = calculate_sum(root.left)
    sum_right = calculate_sum(root.right)

    sum_of_children = sum_left + sum_right

    value = root.data
    root.data = sum_of_children
    return sum_of_children + value


def is_leaf(node):
    return node.left is None and node.right is None


if __name__ == '__main__':
    _r = Node(10)
    _r.left = Node(-2)
    _r.right = Node(6)
    _r.left.left = Node(8)
    _r.left.right = Node(-4)
    _r.right.left = Node(7)
    _r.right.right = Node(5)

    r = get_sum_tree(_r)
    print r, r.left, r.left.left


def is_sum_tree(root):
    if root is None:
        return True, 0
예제 #21
0
    if root is None:
        return True, 0

    is_left_balanced, left_height = is_balanced_bt(root.left)
    is_right_balanced, right_height = is_balanced_bt(root.right)

    if is_left_balanced and is_right_balanced:
        return abs(left_height -
                   right_height) <= 1, max(left_height, right_height) + 1

    return False, max(left_height, right_height) + 1


if __name__ == '__main__':
    # balanced
    root = Node(1)
    root.left = Node(1)
    root.right = Node(1)
    root.left.left = Node(1)
    root.left.right = Node(1)
    root.left.right.left = Node(1)
    root.right.right = Node(1)

    print is_balanced_bt(root)

    # not balanced
    root = Node(1)
    root.left = Node(1)
    root.right = Node(1)
    root.left.left = Node(1)
    root.left.right = Node(1)
예제 #22
0
        if is_leaf(root):
            return True

        l = root.left.data if root.left else 0
        r = root.right.data if root.right else 0

        if l + r == root.data:
            return is_child_sum_met(root.left) and is_child_sum_met(root.right)

        return False

    return True


if __name__ == '__main__':
    root = Node(10)
    root.left = Node(8)
    root.right = Node(2)
    root.left.left = Node(3)
    root.left.right = Node(5)
    root.right.left = Node(2)

    print is_child_sum_met(root)
"""
amzn

#tricky
http://www.geeksforgeeks.org/convert-an-arbitrary-binary-tree-to-a-tree-that-holds-children-sum-property/
"""

예제 #23
0
    global MAX_VAL
    if root is None:
        return 0

    l_sum = max(0, max_sum_path(root.left))
    r_sum = max(0, max_sum_path(root.right))

    # update max seen so far, l_sum = 0 means l_sum not considered
    MAX_VAL = max(MAX_VAL, l_sum + r_sum + root.data)

    # for parent use only one path. i.e. biggest path
    return max(l_sum, r_sum) + root.data


if __name__ == '__main__':
    r = Node(10)
    r.left = Node(2)
    r.right = Node(10)
    r.left.left = Node(20)
    r.left.right = Node(1)
    r.right.right = Node(-25)
    r.right.right.left = Node(3)
    r.right.right.right = Node(4)

    max_sum_path(r)
    print MAX_VAL


"""
attempting some stuff
"""
예제 #24
0
        return True, right_node_dist + 1, right_min_dist

    return False, 0, 0


def get_dist_of_closest_leaf(root, node):
    is_found, ld, min_dist = find_closest(root, node)

    if is_found:
        return min_dist

    return None


if __name__ == '__main__':
    r = Node('A')
    r.left = Node('B')
    r.right = Node('C')
    r.right.left = Node('E')
    r.right.right = Node('F')
    r.right.left.left = Node('G')
    r.right.right.right = Node('H')
    r.right.left.left.left = Node('I')
    r.right.left.left.right = Node('J')
    r.right.right.right.left = Node('K')

    print get_dist_of_closest_leaf(r, 'H')
    print get_dist_of_closest_leaf(r, 'C')
    print get_dist_of_closest_leaf(r, 'E')
    print get_dist_of_closest_leaf(r, 'B')
예제 #25
0
The maximum of them is 17 and the path for maximum is 7->10.

          10
       /      \
    -2        7
   /   \
8      -4

http://www.geeksforgeeks.org/find-the-maximum-sum-path-in-a-binary-tree/
"""
from G4G.Problems.bst.vertical_sum import Node


def max_sum_path(root, curr_sum):
    if root is None:
        return curr_sum

    l_sum = max_sum_path(root.left, curr_sum + root.data)
    r_sum = max_sum_path(root.right, curr_sum + root.data)
    return max(l_sum, r_sum)


if __name__ == '__main__':
    r = Node(10)
    r.left = Node(-2)
    r.right = Node(7)
    r.left.left = Node(12)
    r.left.right = Node(-4)

    print max_sum_path(r, 0)
예제 #26
0
                # set this to none or in the next iteration it gets
                # pushed to s2 again
                root2 = None

            else:
                s2.pop()
                root2 = root2.right
                root1 = None

        else:
            break


if __name__ == '__main__':
    r1 = Node(5)
    r1.left = Node(1)
    r1.right = Node(10)
    r1.left.left = Node(0)
    r1.left.right = Node(4)
    r1.right.left = Node(7)
    r1.right.left.right = Node(9)

    r2 = Node(10)
    r2.left = Node(7)
    r2.right = Node(20)
    r2.left.left = Node(4)
    r2.left.right = Node(9)

    print_common_nodes(r1, r2)
예제 #27
0
    if left_tail:
        left_tail.right = root
        root.left = left_tail
        head = left_head

    if right_head:
        root.right = right_head
        right_head.left = root
        tail = right_tail

    return head, tail


if __name__ == '__main__':
    r = Node(10)
    r.left = Node(12)
    r.right = Node(15)
    r.left.left = Node(25)
    r.left.right = Node(30)
    r.right.left = Node(36)

    ll_head, ll_tail = bt_to_dll(r)

    iterator = ll_head
    while iterator:
        print iterator,
        iterator = iterator.right
"""
http://www.geeksforgeeks.org/convert-a-binary-tree-to-a-circular-doubly-link-list/
"""
http://www.geeksforgeeks.org/find-pair-root-leaf-path-sum-equals-roots-data/
"""
from G4G.Problems.bst.vertical_sum import Node


def find_pair(root, hm, r_data):
    if root:
        if hm.get(r_data - root.data):
            print 'YES', root.data, r_data - root.data
            return

        hm[root.data] = True
        find_pair(root.left, hm, r_data)
        find_pair(root.right, hm, r_data)
        hm[root.data] = False


if __name__ == '__main__':
    r = Node(8)
    r.left = Node(5)
    r.right = Node(4)
    r.left.left = Node(9)
    r.left.right = Node(7)
    r.right.right = Node(11)
    r.left.right.right = Node(12)
    r.left.right.left = Node(1)

    find_pair(r, {}, r.data)
예제 #29
0
def double_node(node):
    lft = node.left
    l_node = Node(node.data)
    l_node.left = lft
    node.left = l_node
    return node
예제 #30
0
        if done1 and done2:
            if val1 != val2:
                return False
            else:
                done1 = False
                done2 = False

        if val1 is None and val2 is None:
            return True

        if val1 is None or val2 is None:
            return False


if __name__ == '__main__':
    r1 = Node(1)
    r1.left = Node(2)
    r1.right = Node(3)
    r1.left.left = Node(4)
    r1.right.left = Node(6)
    r1.right.right = Node(7)

    r2 = Node(0)
    r2.left = Node(5)
    r2.right = Node(8)
    r2.left.right = Node(4)
    r2.right.left = Node(6)
    r2.right.right = Node(7)

    print is_leaf_order_same(r1, r2)