def delete(self, num: int, node: TreeNode = None): node = node or self.root if num < node.val: node.left = self.delete(num, node.left) elif num > node.val: node.right = self.delete(num, node.right) else: self.size -= 1 if node.left is None and node.right is None: if self.root == node: self.root = None return None elif node.left is None: if self.root == node: self.root = node.right return node.right elif node.right is None: if self.root == node: self.root = node.left return node.left else: min_node = node.right while min_node.left: min_node = min_node.left node.val = min_node.val node.right = self.delete(min_node.val, node.right) return node
def delete(self, node: TreeNode, val: int): if node is None: return if val < node.val: node.left = self.delete(node.left, val) if val > node.val: node.right = self.delete(node.right, val) if val == node.val: if node.left and node.right: predecessor = node.left while predecessor.right: predecessor = predecessor.right node.val = predecessor.val predecessor.val = val node.left = self.delete(node.left, val) elif node.left: return node.left elif node.right: return node.right else: return None return node
def deserialize(self, data): """Decodes your encoded data to tree. :type data: str :rtype: TreeNode """ if len(data) == 0: return None root = TreeNode(data[0]) idx = 1 dq = deque([root]) while dq and idx < len(data): cur_node = dq.popleft() if data[idx] is not None: cur_node.left = TreeNode(data[idx]) dq.append(cur_node.left) idx += 1 if idx < len(data) and data[idx] is not None: cur_node.right = TreeNode(data[idx]) dq.append(cur_node.right) idx += 1 return root
def insertNode(self, node: TreeNode, val: int): if node.val is None or val > node.val: if node.right: self.insertNode(node.right, val) else: node.right = TreeNode(val) elif val < node.val: if node.left: self.insertNode(node.left, val) else: node.left = TreeNode(val)
def helper(left: int, right: int): if left > right: return None mid = (left + right) // 2 root = TreeNode(nums[mid]) root.left = helper(left, mid - 1) root.right = helper(mid + 1, right) return root
def rdeserialize(l: List[str]) -> TreeNode: if l[0] == "None": l.pop(0) return None root = TreeNode(l[0]) l.pop(0) root.left = rdeserialize(l) root.right = rdeserialize(l) return root
def helper(l_idx: int, r_idx: int) -> TreeNode: if l_idx > r_idx: return None val = preorder.pop(0) node = TreeNode(val) idx = idx_map[val] node.left = helper(l_idx, idx - 1) node.right = helper(idx + 1, r_idx) return node
def insert(self, node: TreeNode, val: int): if node is None or node.val == val: return if val < node.val: if node.left: self.insert(node.left, val) else: node.left = TreeNode(val) if val > node.val: if node.right: self.insert(node.right, val) else: node.right = TreeNode(val)
def helper(in_left = 0, in_right = len(inorder)) -> TreeNode: nonlocal pre_idx if in_left == in_right: return None val = preorder[pre_idx] node = TreeNode(val) pre_idx += 1 idx = idx_map[val] node.left = helper(in_left, idx) node.right = helper(idx + 1, in_right) return node
def helper(in_left: int, in_right: int) -> TreeNode: if in_left > in_right: return None # pick up the last element as a root val = postorder.pop() root = TreeNode(val) # root splits inorder list # into left and right subtree index = idx_map[val] # build right subtree root.right = helper(index + 1, in_right) # build left subtree root.left = helper(in_left, index - 1) return root
def test_bst(): bst = BST() root = TreeNode(5) assert inorder_traverse(root) == [5] bst.insert(root, 2) assert inorder_traverse(root) == [2, 5] bst.insert(root, 8) assert inorder_traverse(root) == [2, 5, 8] bst.insert(root, 1) assert inorder_traverse(root) == [1, 2, 5, 8] bst.insert(root, 6) assert inorder_traverse(root) == [1, 2, 5, 6, 8] bst.insert(root, 7) assert inorder_traverse(root) == [1, 2, 5, 6, 7, 8] bst.insert(root, 12) assert inorder_traverse(root) == [1, 2, 5, 6, 7, 8, 12] bst.insert(root, 9) assert inorder_traverse(root) == [1, 2, 5, 6, 7, 8, 9, 12] bst.insert(root, 13) assert inorder_traverse(root) == [1, 2, 5, 6, 7, 8, 9, 12, 13] assert bst.search(root, 5) == True assert bst.search(root, 3) == False # if left and right exist bst.delete(root, 8) assert inorder_traverse(root) == [1, 2, 5, 6, 7, 9, 12, 13] # if left and right is None bst.delete(root, 1) assert inorder_traverse(root) == [2, 5, 6, 7, 9, 12, 13] bst.delete(root, 2) assert inorder_traverse(root) == [5, 6, 7, 9, 12, 13] # if left is None bst.delete(root, 7) assert bst.search(root, 7) == False assert inorder_traverse(root) == [5, 6, 9, 12, 13] # if right is None bst.insert(root, 2) bst.insert(root, 1) bst.delete(root, 2) assert inorder_traverse(root) == [1, 5, 6, 9, 12, 13] # delete root node bst.delete(root, 5) assert inorder_traverse(root) == [1, 6, 9, 12, 13]
def insert(self, num: int): self.size += 1 if self.root is None: self.root = TreeNode(num) return node = self.root while node: if num < node.val: if not node.left: node.left = TreeNode(num) return node = node.left else: if not node.right: node.right = TreeNode(num) return node = node.right
def run_branch_and_bound(self, data): start_time = time.time() self.vertex_count = len(data) data = numpy.array(data) #ensure all the zeros or negative values are set to inifinity, #zero has a special meaining for this algorithnm data[data <= 0] = math.inf #set the upper bound to infinity self.upper_bound = math.inf #perform the initial reduction and get the lower bound starting_reduced_matrix, lower_bound = self.calculate_reduction( data, 0, 0) #created the first node in the state space tree tree_nodes = [] working_node = TreeNode(1, 1, starting_reduced_matrix, lower_bound, 0, [1], 0, -1) tree_nodes.append(working_node) while (working_node != None): #do a deep dive to the first leaf working_path, working_bound, working_node = self.deep_dive_from_node( working_node.vertex_id, working_node, tree_nodes) #if we have a loop set the upper bound else keep looking for a loop if working_path[0] == working_path[-1]: status = "searched" #set upper bound to the result of the dive if lower if working_bound < self.upper_bound: self.upper_bound = working_bound self.best_path = working_path else: status = "pruned" while working_node.number_of_children < 2: if working_node.vertex_id != self.start_vertex: working_node.status = status working_node = self.find_node_in_list_by_node_id( working_node.parent_node_id, tree_nodes) if (working_node == None): break return self.upper_bound, self.best_path, time.time() - start_time
def sortedArrayToBST(self, nums: List[int]) -> TreeNode: def dfs(node, start: int, end: int): mid = (start + end) // 2 self.insertNode(node, nums[mid]) if start < mid: dfs(node, start, mid - 1) if mid < end: dfs(node, mid + 1, end) dummy_node = TreeNode(None) dfs(dummy_node, 0, len(nums) - 1) return dummy_node.right
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode: if not inorder: return None idx_map = {val: idx for idx, val in enumerate(inorder)} dq = deque(preorder) root = TreeNode(dq.popleft()) stack = [root] while dq: val = dq.popleft() node = TreeNode(val) # left if idx_map[val] < idx_map[stack[-1].val]: stack[-1].left = node else: # right while stack and idx_map[stack[-1].val] < idx_map[val]: u = stack.pop() u.right = node stack.append(node) return root
def find_lowest_cost_next_vertex(self, parent_node, nodes_list): available_vertices = self.get_possible_edges_for_vertex(parent_node) lowest_cost = math.inf least_cost_vertex = 0 least_cost_node = None for vertex in available_vertices: # need to copy this every loop to prevent carry over changes path = copy.deepcopy(parent_node.path_so_far) matrix = copy.deepcopy(parent_node.reduced_matrix) path.append(vertex) # check for existing node in the list by path exiting_node = self.find_node_in_list_by_path(path, nodes_list) if (exiting_node != None): if (exiting_node.status != "pruned" and exiting_node.status != "searched"): tree_node = exiting_node else: #reduce the number of children of the parent node parent_node.number_of_children = parent_node.number_of_children - 1 continue else: # actual cost of going between current vertices actual_cost = matrix[parent_node.index_in_matrix, vertex - 1] # reduced matrix and cost for node being calculated reduced_matrix, reduction_cost = self.calculate_reduction( matrix, parent_node.vertex_id, vertex) cost = reduction_cost + parent_node.cost + actual_cost # add node to the list since we have calculated it tree_node = TreeNode( len(nodes_list) + 1, vertex, reduced_matrix, cost, vertex - 1, path, parent_node.node_id, -1) nodes_list.append(tree_node) if tree_node.cost < lowest_cost: lowest_cost = tree_node.cost least_cost_vertex = tree_node.vertex_id least_cost_node = tree_node return least_cost_vertex, least_cost_node, nodes_list