def set(self, key, value): """Insert the given item in order into this binary search tree. Best case: O(1) when adding to empty tree Worst case: O(log n) when node is lowest level of tree""" # Handle the case where the tree is empty key_value = (key, value) if self.is_empty(): self.root = BinaryTreeNode(key_value) self.size += 1 return parent = self._find_parent_node_recursive(key, self.root) if key < parent.data[0]: if (parent.left == None): self.size += 1 parent.left = BinaryTreeNode(key_value) else: parent.left.data = key_value elif key > parent.data[0]: if (parent.right == None): self.size += 1 parent.right = BinaryTreeNode(key_value) else: parent.right.data = key_value
def insertIntoBST1(self, root: BinaryTreeNode, val: int) -> BinaryTreeNode: if root is None: return BinaryTreeNode(val) if val < root.val: root.left = self.insertIntoBST1(root.left, val) else: # val > root.val root.right = self.insertIntoBST1(root.right, val) return root
def create_minimal_tree(list_of_values: List[int]) -> BinaryTreeNode: length_of_list = len(list_of_values) if length_of_list == 1: node = BinaryTreeNode(list_of_values[0]) return node middle_index = floor(length_of_list/2) left_tree_root: BinaryTreeNode = create_minimal_tree(list_of_values[0:middle_index]) right_tree_root: BinaryTreeNode = create_minimal_tree(list_of_values[middle_index+1:length_of_list]) root_node: BinaryTreeNode = BinaryTreeNode(list_of_values[middle_index], left_tree_root, right_tree_root) return root_node
def create_tree_from_list(values: List[int], root: BinaryTreeNode, parent: BinaryTreeNode, i: int, length: int) -> BinaryTreeNode: """Helper function to create a tree from a list of values. """ if i < length: if values[i] is not None: root = BinaryTreeNode(data=values[i], parent=parent) root.left = create_tree_from_list(values, root.left, root, 2 * i + 1, length) root.right = create_tree_from_list(values, root.right, root, 2 * i + 2, length) return root
def to_search_tree(sorted_list): print("List:", sorted_list) if len(sorted_list) == 0: print("Empty list, returning None") return None elif len(sorted_list) == 1: print("Single entry, creating new node") return BinaryTreeNode(sorted_list[0]) else: print("2 or more entries. Splitting and recursing.") mid = len(sorted_list)//2 root = BinaryTreeNode(sorted_list[mid]) print("Root (midpoint of split):", root) root.left = to_search_tree(sorted_list[:mid]) root.right = to_search_tree(sorted_list[mid+1:]) return root
def to_search_tree(sorted_list): print("List:", sorted_list) if len(sorted_list) == 0: print("Empty list, returning None") return None elif len(sorted_list) == 1: print("Single entry, creating new node") return BinaryTreeNode(sorted_list[0]) else: print("2 or more entries. Splitting and recursing.") mid = len(sorted_list) // 2 root = BinaryTreeNode(sorted_list[mid]) print("Root (midpoint of split):", root) root.left = to_search_tree(sorted_list[:mid]) root.right = to_search_tree(sorted_list[mid + 1:]) return root
def insertIntoBST2(self, root: BinaryTreeNode, val: int) -> BinaryTreeNode: if root is None: return BinaryTreeNode(val) parent, curr = None, root while curr: parent = curr if val < curr.val: curr = curr.left elif val > curr.val: curr = curr.right else: # val == root.val break if val < parent.val: parent.left = BinaryTreeNode(val) elif val > parent.val: parent.right = BinaryTreeNode(val) return root
def rebuild_tree(preorder, prestart, inorder, instart, inend): print preorder, prestart, inorder, instart, inend if instart > inend: return None node = BinaryTreeNode(preorder[prestart]) if instart == inend: return node in_index = findindex(inorder, instart, inend, preorder[prestart]) print in_index if prestart + 1 > len(preorder): return node node.left = rebuild_tree(preorder, prestart + 1, inorder, instart, in_index - 1) if in_index + 1 > len(preorder): return node node.right = rebuild_tree(preorder, in_index + 1, inorder, in_index + 1, inend) return node
def build(preorder_left, preorder_right, inorder_left, inorder_right): # base if preorder_left > preorder_right: return None # process preorder_root = preorder_left inorder_root = index[preorder[preorder_root]] root = BinaryTreeNode(preorder[preorder_root]) # drill down size_left_subtree = inorder_root - inorder_left root.left = build(preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root + 1) root.right = build(preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right) # return return root
def deleteNode(self, root: BinaryTreeNode, key: int) -> BinaryTreeNode: if root is None: return None if key < root.val: root.left = self.deleteNode(root.left, key) elif key > root.val: root.right = self.deleteNode(root.right, key) else: if root.left is None: # has only right child child = root.right root = None return child elif root.right is None: # has only left child child = root.left root = None return child # has two children child = self.minChild(root.right) root.val = child.val root.right = self.deleteNode(root.right, child.val) return root
def test_breadth_first_mostly_left_side_nodes(self): bt = BinaryTree() bt.root = BinaryTreeNode(1) bt.root.left = BinaryTreeNode(2) bt.root.right = BinaryTreeNode(3) bt.root.left.left = BinaryTreeNode(4) bt.root.left.right = BinaryTreeNode(5) bt.root.right.right = BinaryTreeNode(7) bt.root.left.left.left = BinaryTreeNode(6) bt.root.left.left.left.left = BinaryTreeNode(8) result, depth = bt.breadth_first() self.assertEqual(result, [1, 2, 3, 4, 5, 7, 6, 8]) self.assertEqual(depth, 4)
def create_tree_ready_for_traversal(): # ____1____ # | | # __2__ __3__ # | | | | # 4 5 6 7 bt = BinaryTree() bt.root = BinaryTreeNode(1) bt.root.left = BinaryTreeNode(2) bt.root.left.left = BinaryTreeNode(4) bt.root.left.right = BinaryTreeNode(5) bt.root.right = BinaryTreeNode(3) bt.root.right.right = BinaryTreeNode(7) bt.root.right.left = BinaryTreeNode(6) return bt
def test_balanced_true_perfect(self): # 1 # / \ # 2 3 # / \ / \ # 4 5 6 7 six_node = BinaryTreeNode("6") seven_node = BinaryTreeNode("7") three_node = BinaryTreeNode("3", six_node, seven_node) four_node = BinaryTreeNode("4") five_node = BinaryTreeNode("5") two_node = BinaryTreeNode("2", four_node, five_node) one_node = BinaryTreeNode("1", two_node, three_node) binary_tree = BinaryTree(one_node) balanced = run_check_balanced(binary_tree) self.assertTrue(balanced)
def test_balanced_false(self): # 1 # / \ # 2 3 # / \ / # 4 5 6 # | # 7 # | # 8 six_node = BinaryTreeNode("6") three_node = BinaryTreeNode("3", six_node) four_node = BinaryTreeNode("4") eight_node = BinaryTreeNode("8") seven_node = BinaryTreeNode("7", eight_node) five_node = BinaryTreeNode("5", seven_node) two_node = BinaryTreeNode("2", four_node, five_node) one_node = BinaryTreeNode("1", two_node, three_node) binary_tree = BinaryTree(one_node) balanced = run_check_balanced(binary_tree) self.assertFalse(balanced)
def better_is_mirror(root: binary_tree.BinaryTreeNode): if root.is_leaf(): return True if root.left is None or root.right is None: return False left_tree_stack = [root.left] right_tree_stack = [root.right] while len(left_tree_stack) != 0 or len(right_tree_stack) != 0: left_node = left_tree_stack.pop() right_node = right_tree_stack.pop() if not compare_node(left_node, right_node): return False dfs_left_tree(left_node, left_tree_stack.append) dfs_right_tree(left_node, right_tree_stack.append) return True
def test_list_of_depths(self): # 1 # / \ # 2 3 # / \ / \ # 4 5 6 7 six_node = BinaryTreeNode("6") seven_node = BinaryTreeNode("7") three_node = BinaryTreeNode("3", six_node, seven_node) four_node = BinaryTreeNode("4") five_node = BinaryTreeNode("5") two_node = BinaryTreeNode("2", four_node, five_node) one_node = BinaryTreeNode("1", two_node, three_node) binary_tree = BinaryTree(one_node) response = run_list_of_depths(binary_tree) list_one: LinkedList = response[0] self.assertEqual('1', list_one.head.data) list_two = response[1] self.assertEqual('2', list_two.head.data) list_three = response[2] self.assertEqual('4', list_three.head.data)
def test_has_parent_attribute(self): node = BinaryTreeNode(10) self.assertIsNone(node.parent)
def test_accepts_parent_node(self): parent_node = BinaryTreeNode(10) node = BinaryTreeNode(20, parent_node) self.assertIs(node.parent, parent_node)
def node_b(): return BinaryTreeNode('b')
def node_a(): return BinaryTreeNode('a')
def node_f(): return BinaryTreeNode('f')
def node_e(): return BinaryTreeNode('e')
def node_d(): return BinaryTreeNode('d')
def node_c(): return BinaryTreeNode('c')
def test_treeToString(): root = BinaryTreeNode( 4, BinaryTreeNode(3, BinaryTreeNode(2, BinaryTreeNode(1)))) assert treeToString(root) == "4(3(2(1)))" balanced = balanceTree(root) assert treeToString(balanced) == "2(1)(3(4))"
def test_accepts_value(self): node = BinaryTreeNode(10) self.assertEqual(node.value, 10)
def test_has_left_attribute(self): node = BinaryTreeNode(10) self.assertIsNone(node.left)
def test_height(self): # Create node with no children node = BinaryTreeNode(4) assert node.height() == 0 # Attach left child node node.left = BinaryTreeNode(2) assert node.height() == 1 # Attach right child node node.right = BinaryTreeNode(6) assert node.height() == 1 # Attach left-left grandchild node node.left.left = BinaryTreeNode(1) assert node.height() == 2 # Attach right-right grandchild node node.right.right = BinaryTreeNode(8) assert node.height() == 2 # Attach right-right-left great-grandchild node node.right.right.left = BinaryTreeNode(7) assert node.height() == 3
def test_is_branch(self): # Create node with no children node = BinaryTreeNode(2) assert node.is_branch() is False # Attach left child node node.left = BinaryTreeNode(1) assert node.is_branch() is True # Attach right child node node.right = BinaryTreeNode(3) assert node.is_branch() is True # Detach left child node node.left = None assert node.is_branch() is True # Detach right child node node.right = None assert node.is_branch() is False
def build_binary_tree(treeFile): tree = BinaryTreeNode() tree.parse_from_string(read_nh_file_into_single_line(treeFile)) interior_nodes = [] tree.assign_idx(interior_nodes, [1]) return tree
def test_init(self): data = 123 node = BinaryTreeNode(data) assert node.data is data assert node.left is None assert node.right is None