Пример #1
0
 def add_value(self, value: T) -> None:
     """
     Add value to this BST
     :param value:
     :return:
     """
     ...
     if self.root:
         return self.root.add_value(value)
     else:
         self.root = BSTNode(value)
         return True
Пример #2
0
 def add_value(self, value: T) -> None:
     """
     Add value to this BST
     Duplicate values should be placed on the right
     :param value:
     :return:
     """
     if self.root:
         return self.root.insert(value)
     else:
         self.root = BSTNode(value)
         return None
Пример #3
0
    def add_value(self, value: T) -> None:
        """
        Add value to this BST
        Duplicate values should be placed on the right
        :param value:
        :return:
        """
        node = BSTNode(value)
        if (self.root is None):
            self.root = node
            node.left = None
            node.right = None
        else:
            cur = self.root
            while (cur is not None):
                if (self.key(node.value) < self.key(cur.value)):
                    if (cur.left is None):
                        node.parent = cur
                        cur.left = node
                        cur = None
                    else:
                        cur = cur.left
                else:
                    if (cur.right is None):
                        node.parent = cur
                        cur.right = node
                        cur = None
                    else:
                        cur = cur.right
            node.left = None
            node.right = None

        self._num_nodes += 1
Пример #4
0
 def test_get_node(self):
     tree = BST()
     tree.add_value(100)
     tree.add_value(80)
     tree.add_value(90)
     tree.add_value(200)
     tree.add_value(70)
     self.assertEqual(BSTNode(70), tree.get_node(70))
Пример #5
0
    def insert_recurse(self, value: T, node: BSTNode[T], key: Callable[[T], K]) -> BSTNode[T]:
        #if node.value == value:
        #    return   # come back and allow dups
        #elif node.value > value:
        if key(node.value) > key(value):
            if node.left:
                return self.insert_recurse(value,node.left,key)
            else:
                node.left = BSTNode(value)
                return

        else:
            if node.right:
                return self.insert_recurse(value,node.right,key)
            else:
                node.right = BSTNode(value)
                return
Пример #6
0
 def test_get_max_node2(self):
     tree = BST()
     tree.add_value(100)
     tree.add_value(80)
     tree.add_value(90)
     tree.add_value(200)
     tree.add_value(70)
     node_to_remove = tree.get_node(80)
     self.assertEqual(BSTNode(90), tree.get_max_node(node_to_remove))
Пример #7
0
    def test_create_tree(self):
        tree = BST()
        fill_int_tree(tree)

        root = BSTNode(100)
        root.left = BSTNode(80)
        root.right = BSTNode(200)
        root.left.left = BSTNode(70)
        root.left.right = BSTNode(90)

        cmp_tree = BST(root)
        self.assertEqual(tree, cmp_tree)
Пример #8
0
 def add_value_helper(self, value: T, root: BSTNode[T]) -> BSTNode[T]:
     if self.root is None:
         return BSTNode(value=value, parent=root)
     elif value < root.value:  # add_left
         root.left = self.add_value_helper(value, root.left)
         root.left.parent = root
     else:  # add right
         root.right = self.add_value_helper(value, root.right)
         root.right.parent = root
     return root
Пример #9
0
 def bst_insert(self, start: BSTNode[T], value: T):
     if start is None:  # found the spot to add the node
         start = BSTNode(value)
     elif self.key(value) < self.key(start.value):  # add_left
         start.left = self.bst_insert(start.left, value)
         start.left.parent = start
     else:  # add right
         start.right = self.bst_insert(start.right, value)
         start.right.parent = start
     return start
Пример #10
0
    def test_remove_internal_node_with_two_children(self):
        tree = BST()
        fill_int_tree(tree)
        tree.add_value(50)
        tree.add_value(95)
        tree.remove_value(80)

        root = BSTNode(100)
        root.left = BSTNode(90)
        root.right = BSTNode(200)
        root.left.left = BSTNode(70)
        root.left.right = BSTNode(95)
        root.left.left.left = BSTNode(50)

        cmp_tree = BST(root)
        self.assertEqual(tree, cmp_tree)
Пример #11
0
    def test_tree_not_eq(self):
        tree = BST()
        fill_int_tree(tree)

        root = BSTNode(100)
        root.left = BSTNode(80)
        root.right = BSTNode(200)
        root.left.left = BSTNode(70)
        root.left.right = BSTNode(92)

        cmp_tree = BST(root)
        cmp_tree._num_nodes = 5
        self.assertNotEqual(tree, cmp_tree)
Пример #12
0
 def add_value(self, value: T) -> None:
     """
     Add value to this BST
     :param value:
     :return:
     """
     self.bst_length += 1
     if self.root:
         return self.insert_recurse(value, self.root, self.key)
     else:
         self.root = BSTNode(value)
         return
Пример #13
0
    def add_value(self, value: T, curNode: BSTNode = None) -> None:
        """
        Add value to this BST
        :param curNode: defaults to None, but is the current node that the algorithm is on
        :param value: the donation amount
        :return: None
        """
        if curNode is None:
            curNode = self.root

        if self.root is None:  # base case- tree is empty so create a node and make it the root
            self.root = BSTNode(value)
            self.length = self.length + 1
        elif self.key(value) == self.key(curNode.value):
            if curNode.getright() == -1:
                curNode.right = BSTNode(value, parent=curNode)
                self.length += 1
            else:
                newNode = curNode.right
                self.add_value(value, newNode)
        elif self.key(value) < self.key(
                curNode.value):  # I think we have to call key on this??
            if curNode.getleft(
            ) == -1:  # in other words, if curNode doesn't have a left child..
                curNode.left = BSTNode(value, parent=curNode)
                self.length = self.length + 1
            else:
                newNode = curNode.left
                self.add_value(
                    value, newNode
                )  # recursive call to continue to find the correct spot for entry

        else:  # self.key(value) > self.key(curNode.right):
            if curNode.getright() == -1:
                curNode.right = BSTNode(value, parent=curNode)
                self.length = self.length + 1
            else:
                self.add_value(value, curNode.right)
Пример #14
0
    def test_create_tree(self):
        tree = BST()
        tree.add_value(100)
        tree.add_value(80)
        tree.add_value(200)
        tree.add_value(90)
        tree.add_value(70)

        root = BSTNode(100)
        root.left = BSTNode(80)
        root.right = BSTNode(200)
        root.left.left = BSTNode(70)
        root.left.right = BSTNode(90)

        cmp_tree = BST(root)
        self.assertEqual(tree, cmp_tree)  # but we don't pass this
Пример #15
0
    def test_create_tree(self):
        tree = BST()
        tree.add_value(100)
        tree.add_value(80)
        tree.add_value(200)
        tree.add_value(90)
        tree.add_value(70)

        root = BSTNode(100)
        root.left = BSTNode(80)
        root.right = BSTNode(200)
        root.left.left = BSTNode(70)
        root.left.right = BSTNode(90)

        cmp_tree = BST(root)
        self.assertEqual(tree, cmp_tree)
        self.assertEqual(tree.height, 2)
        self.assertEqual(len(tree), 5)
Пример #16
0
    def test_delete_4(self):
        tree = BST()
        tree.add_value(100)
        tree.add_value(80)
        tree.add_value(200)
        tree.add_value(300)
        tree.add_value(150)

        tree.remove_value(200)

        root = BSTNode(100)
        root.left = BSTNode(80)
        root.right = BSTNode(150)
        root.right.right = BSTNode(300)

        cmp_tree = BST(root)
        self.assertEqual(tree, cmp_tree)
Пример #17
0
from Trees.src.nodes.bst_node import BSTNode
from Trees.src.trees.bst_tree import BST

if __name__ == '__main__':
    a = BSTNode(50)
    b = BSTNode(40)
    c = BSTNode(35)
    d = BSTNode(37)
    e = BSTNode(45)
    f = BSTNode(90)

    a.left = b
    b.left = c 
    c.right = d
    b.right = e

    print ( "create tree with 5 nodes")
    tree = BST(a)
    print ("len ex 5: ", len(tree))
    print ("add node", tree.add_value(100))
    print ("len ex 6: ", len(tree))
    print ("remove node", tree.remove_value(50))
    print ("len ex 5: ", len(tree))

    results = []
    tree.inorder(results)
    for x in results:
        print (x.value)


    print ("\n Testing adding children")
Пример #18
0
from Trees.src.nodes.bst_node import BSTNode
from Trees.src.trees.bst_tree import BST

if __name__ == '__main__':
    a = BSTNode(50)
    b = BSTNode(40)
    c = BSTNode(35)
    d = BSTNode(37)
    e = BSTNode(45)

    a.left = b
    b.left = c
    c.right = d
    b.right = e

    tree = BST(a)
    print("Tree height:", tree.height())
    print("Tree length:", len(tree))
    node_min = tree.get_min_node()
    print("Tree min:", node_min.value)
    node_max = tree.get_max_node()
    print("Tree max:", node_max.value)
    node_45 = tree.get_node(45)
    print("Tree 45", node_45.value)
    node_50 = tree.get_node(50)
    print("Tree 50", node_50.value)
    new_tree = BST()
    new_tree.add_value(100)
    new_tree.add_value(75)
    new_tree.add_value(200)
    new_tree.add_value(300)
Пример #19
0
 def test_create_node(self):
     node = BSTNode(100)
     self.assertEqual(node.value, 100)
     self.assertIsNone(node.left, None)
     self.assertIsNone(node.right, None)
Пример #20
0
 def test_init_(self,
                root: Optional[BSTNode[T]] = None,
                key: Callable[[T], K] = lambda x: x) -> None:
     node = BSTNode(45)
     tree = BST(node)
     self.assertEqual(tree.get_node(45).value, 45)
Пример #21
0
class BST(Generic[T, K]):
    """
    T: The value stored in the node
    K: The value used in comparing nodes
    """
    def __init__(self,
                 root: Optional[BSTNode[T]] = None,
                 key: Callable[[T], K] = lambda x: x) -> None:
        """
        You must have at least one member named root

        :param root: The root node of the tree if there is one.
        If you are provided a root node don't forget to count how many nodes are in it
        :param key: The function to be applied to a node's value for comparison purposes.
        It serves the same role as the key function in the min, max, and sorted builtin
        functions
        """
        self.root = None
        self.key = None

        ...

    @property
    def height(self) -> int:
        """
        Compute the height of the tree. If the tree is empty its height is -1
        :return:

        """
        if self.root:
            return self.root.Height()
        elif self.root is None:
            return -1
        else:
            return 0

    def __len__(self) -> int:
        """
        :return: the number of nodes in the tree
        """
        if self.root:
            return self.root.__len__()
        else:
            return 0

    def add_value(self, value: T) -> None:
        """
        Add value to this BST
        :param value:
        :return:
        """
        ...
        if self.root:
            return self.root.add_value(value)
        else:
            self.root = BSTNode(value)
            return True

    def get_node(self, value: K) -> BSTNode[T]:
        """
        Get the node with the specified value
        :param value:
        :raises MissingValueError if there is no node with the specified value
        :return:
        """
        if self.root:
            return self.root.get_node(value)
        elif self.root is None:
            raise MissingValueError
        else:
            return False

    def get_max_node(self) -> BSTNode[T]:
        """
        Return the node with the largest value in the BST
        :return:
        :raises EmptyTreeError if the tree is empty
        """
        if self.root:
            return self.root.get_max_node()
        elif self.root is None:
            raise EmptyTreeError
        else:
            return 0

    def get_min_node(self) -> BSTNode[T]:
        """
        Return the node with the smallest value in the BST
        :return:
        """
        if self.root:
            return self.root.get_min_node()
        elif self.root is None:
            raise EmptyTreeError
        else:
            return 0

    def remove_value(self, value: T) -> None:
        """
        Remove the node with the specified value.
        When removing a node with 2 children take the successor for that node
        to be the largest value smaller than the node (the max of the
        left subtree)
        :param value:
        :return:
        :raises MissingValueError if the node does not exist
        """

        if self.root:
            self.root.remove_value(value)
        elif self.root is None:
            raise MissingValueError

    def __eq__(self, other: object) -> bool:
        if self is other:
            return True
        elif isinstance(other, BST):
            if len(self) == 0 and len(other) == 0:
                return True
            else:
                return len(self) == len(other) and self.root.value == other.root.value and \
                       all((BST(c1) == BST(c2) for c1, c2 in zip(self.root, other.root)))
        else:
            return False

    def __ne__(self, other: object) -> bool:
        return not (self == other)
    def test_add_node_with_two_children(self):
        a = BSTNode(50)
        b = BSTNode(40)
        c = BSTNode(35)
        d = BSTNode(37)
        e = BSTNode(45)
        f = BSTNode(90)
        g = BSTNode(150)

        a.left = b
        b.left = c
        c.right = d
        b.right = e

        m = BSTNode(65, children = [a,f])
        tree1 = BST(m)
        self.assertEqual(len(tree1), 7)
    def test_add_parent(self):
        a = BSTNode(50)
        b = BSTNode(40)
        c = BSTNode(35)
        d = BSTNode(37)
        e = BSTNode(45)
        f = BSTNode(90)
        g = BSTNode(150)

        a.left = b
        b.left = c
        c.right = d
        b.right = e

        p = BSTNode(200)
        n = BSTNode(75, children = [f, g], parent = p)

        tree2 = BST(p)
        self.assertEqual(len(tree2), 4)
Пример #24
0
class BST(Generic[T, K]):
    """
    T: The value stored in the node
    K: The value used in comparing nodes
    """
    def __init__(self,
                 root: Optional[BSTNode[T]] = None,
                 key: Callable[[T], K] = lambda x: x) -> None:
        """
        You must have at least one member named root

        :param root: The root node of the tree if there is one.
        If you are provided a root node don't forget to count how many nodes are in it
        :param key: The function to be applied to a node's value for comparison purposes.
        It serves the same role as the key function in the min, max, and sorted builtin
        functions
        """
        self.root = root
        self.key = key

    @property
    def height(self) -> int:
        """
        Compute the height of the tree. If the tree is empty its height is -1
        :return:
        """
        def get_height(node):
            if node.left and node.right:
                return 1 + max(get_height(node.left), get_height(node.right))
            elif node.left:
                return 1 + get_height(node.left)
            elif node.right:
                return 1 + get_height(node.right)
            else:
                return 0

        if self.root:
            return get_height(self.root)
        else:
            return -1

    def __len__(self) -> int:
        """
        :return: the number of nodes in the tree
        """
        def get_length(node):
            if not node:
                return 0
            else:
                if node.right and node.left:
                    return 1 + get_length(node.left) + get_length(node.right)
                elif node.right:
                    return 1 + get_length(node.right)
                elif node.left:
                    return 1 + get_length(node.left)
                else:
                    return 1

        return get_length(self.root)

    def add_value(self, value: T) -> None:
        """
        Add value to this BST
        Duplicate values should be placed on the right
        :param value:
        :return:
        """
        if self.root:
            return self.root.insert(value)
        else:
            self.root = BSTNode(value)
            return None

    def remove_value(self, value: K) -> None:
        """
        Remove the node with the specified value.
        When removing a node with 2 children take the successor for that node
        to be the largest value smaller than the node (the max of the
        left subtree)
        :param value:
        :return:
        :raises MissingValueError if the node does not exist
        """
        if self.root:
            return self.root.remove(value)
        else:
            raise MissingValueError

    def get_node(self, value: K) -> BSTNode[T]:
        """
        Get the node with the specified value
        :param value:
        :raises MissingValueError if there is no node with the specified value
        :return:
        """
        if self.root:
            return self.root.get(int(value))
        else:
            raise MissingValueError

    def get_max_node(self) -> BSTNode[T]:
        """
        Return the node with the largest value in the BST
        :return:
        :raises EmptyTreeError if the tree is empty
        """
        if self.root:
            return self.root.get_max()
        else:
            raise EmptyTreeError

    def get_min_node(self) -> BSTNode[T]:
        """
        Return the node with the smallest value in the BST
        :return:
        """
        if self.root:
            return self.root.get_min()
        else:
            raise EmptyTreeError

    def __eq__(self, other: object) -> bool:
        if self is other:
            return True
        elif isinstance(other, BST):
            if len(self) == 0 and len(other) == 0:
                return True
            else:
                return len(self) == len(other) and self.root.value == other.root.value and \
                       BST(self.root.left) == BST(other.root.left) and \
                       BST(self.root.right) == BST(other.root.right)
        else:
            return False

    def __ne__(self, other: object) -> bool:
        return not (self == other)

    def __deepcopy__(self, memodict) -> "BST[T,K]":
        """
        I noticed that for some tests deepcopying didn't
        work correctly until I implemented this method so here
        it is for you
        :param memodict:
        :return:
        """
        new_root = copy.deepcopy(self.root, memodict)
        new_key = copy.deepcopy(self.key, memodict)
        return BST(new_root, new_key)