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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 6
0
        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
Ejemplo n.º 8
0
    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
Ejemplo n.º 11
0
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
Ejemplo n.º 13
0
    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
Ejemplo n.º 16
0
 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