def test_post_order_traversal(): for nodes, expected_result in [ ( ( 8, [(4, [2, 6]), (10, [None, 20])] ), "2->6->4->20->10->8" ), ( (1, ), "1" ), ( (1, [2]), "2->1" ), ( (1, [None, 2]), "2->1" ), ]: result = [] def visit(node: Node) -> None: result.append(node.val) bt = BinaryTree(BinaryTree.build(nodes)) bt.post_order(visit) result = "->".join([str(val) for val in result]) assert result == expected_result, "{} != {}".format(result, expected_result)
def test_insert_method_for_BT(): bt = BinaryTree(BinaryTree.build(SIMPLE_TREE)) for use_case, *expected_result in [ (1, True, True, """ -- 8 | |-- 4 | | |-- 2 | | | |-- 1 | | |-- 6 | |-- 10 | | |-- 20"""), (0, True, True, """ -- 8 | |-- 4 | | |-- 2 | | | |-- 1 | | | |-- 0 | | |-- 6 | |-- 10 | | |-- 20"""), (3, True, True, """ -- 8 | |-- 4 | | |-- 2 | | | |-- 1 | | | | |-- 3 | | | |-- 0 | | |-- 6 | |-- 10 | | |-- 20"""), (8, False, True, """ -- 8 | |-- 4 | | |-- 2 | | | |-- 1 | | | | |-- 3 | | | |-- 0 | | |-- 6 | |-- 10 | | |-- 20"""), ]: insert_result, find_result, tree_repr = expected_result result = bt.insert(use_case) assert result == insert_result, "{} != {}".format(result, insert_result) result = bt.find(use_case) assert result == find_result, "{} != {}".format(result, find_result) assert str(bt) == tree_repr, "{} != {}".format(str(bt), tree_repr)
return None if len(node.nodes) > 1 and node.nodes[1] is not None: return find_right_left_most_node(node) # we need to check the parent # we may be the left child, thus we need to return parent # we may be the right child, we need to go to grandpa while node.parent and node.parent.nodes[0] != node: node = node.parent return node.parent bt = BinaryTree(BinaryTree.build((8, [(4, [2, 6]), (10, [None, 20])]))) for use_case, expected_result in [ (4, 6), (6, 8), (10, 20), (20, None), ]: node = bt.find_node(use_case) result = find_successor(node) if not expected_result: assert result is None, "{} is not None".format(result) else: if result is None: assert False, "None != {}".format(expected_result)
if root.left == None and root.right == None: return 1 return 1 + max(height(root.left), height(root.right)) def diameter(root): if not root: return 0 h1 = height(root.left) h2 = height(root.right) dl = diameter(root.left) dr = diameter(root.right) return max(h1+h2, max(dl, dr)) def optimizedDiameter(root): if not root: return [0, 0] left = optimizedDiameter(root.left) right = optimizedDiameter(root.right) height_till_now = max(left[0], right[0]) + 1 diameter_till_now = max(left[0] + right[0], max(left[1], right[1])) return [height_till_now, diameter_till_now] t = BinaryTree() t.build([1, 2, 3, 4, 5]) print("Diameter: ", diameter(t.root)) print("Diameter: ", optimizedDiameter(t.root)[1])
from tree import BinaryTree import sys # Note: if duplicate is not allowed then remove = def valid_bst(root): def helper(root, left_min, right_max): if not root: return True if (left_min <= root.val and root.val <= right_max and helper(root.left, left_min, root.val) and helper(root.right, root.val, right_max)): return True return False return helper(root, -sys.maxsize, sys.maxsize) if __name__ == "__main__": arr = [5, 4, 6, None, None, 3, 7] t = BinaryTree() t.build(arr) ans = valid_bst(t.root) print(ans)
# if there is one NULL in left or then take non null value # if both are non null then it is the lca # if both values are present into the same subtree then top will be the lca. def lca(root, p, q): if not root or root.val == p.val or root.val == q.val: return root print(root.val, end="->") left = lca(root.left, p, q) right = lca(root.right, p, q) if left and right: # one element is in left side and other is no right side. return root elif left: # element is left return left else: # not in left then either right or both none return right t = BinaryTree() t.build([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]) p = t.search(5) q = t.search(4) lca_node = lca(t.root, p, q) print(f"LCA: {lca_node.val}")
def test_is_not_balanced(): for nodes in IMBALANCED_TREES: bt = BinaryTree(BinaryTree.build(nodes)) assert not bt.is_balanced, "Tree {} is balanced".format(bt)
def test_that_a_tree_is_not_perfect(): for raw_nodes in IMPERFECT_TREES: bt = BinaryTree(BinaryTree.build(raw_nodes)) assert not bt.is_perfect, "Tree {} is perfect".format(bt)
def test_that_a_tree_is_full(): for raw_nodes in NOT_FULL_TREES: bt = BinaryTree(BinaryTree.build(raw_nodes)) assert not bt.is_full, "Tree {} is full".format(bt)
def test_that_a_tree_is_incompleted(): for raw_nodes in INCOMPLETE_TREES: bt = BinaryTree(BinaryTree.build(raw_nodes)) assert not bt.is_complete, "Tree {} is complete".format(bt)
__helper(root.right, l+1) __helper(root, 0) def right_view(root, h): visited = [0]*h def __helper(root, l): if not root: return if not visited[l]: print(root.val, end=" ") visited[l] = 1 __helper(root.right, l+1) __helper(root.left, l+1) __helper(root, 0) t = BinaryTree() t.build([1,2,3,None,5,None,4]) print("Left: ", end=" ") left_view(t.root, t.height()) print("\nRight: ", end=" ") right_view(t.root, t.height())