Example #1
0
def test_node_set_get():
    """Test that node attributes can be changed and accessed."""
    from bst import BSTNode
    node = BSTNode(10)
    another_node = BSTNode(15)
    node.set_right_child(another_node)
    assert node.get_right_child() is another_node
Example #2
0
    def test_count_root(self):
        root = BSTNode(10, 10, None)
        tree = BST(root)
        node = BSTNode(15, 10, None)
        tree.AddKeyValue(15, 10)

        self.assertEqual(tree.Count(), 2)
Example #3
0
 def minimal_tree_recur(elements, low, high):
     if low == high:
         return None
     index = (low + high) // 2
     node = BSTNode(elements[index])
     node.left = minimal_tree_recur(elements, low, index)
     node.right = minimal_tree_recur(elements, index + 1, high)
     return node
 def test1_empty_node_init(self):
     """BSTNodes are initialized with key, value, left and right instance variables. (0p)"""
     node = BSTNode(1)
     self.assertEqual(node.key, 1)
     self.assertIsNone(node.value)
     self.assertIsNone(node.left)
     self.assertIsNone(node.right)
     node = BSTNode(1, 'a')
     self.assertEqual(node.value, 'a')
Example #5
0
    def test_size(self):
        node = BSTNode("e")
        assert node.size() == 1

        node.add("g")
        node.add("o")
        node.add("h")
        node.add("k")
        node.add("m")
        node.add("l")
        assert node.size() == 7
Example #6
0
 def test_add(self, capsys):
     node = BSTNode(STestClass("Memento", "11/10/2000"))
     assert node._element == STestClass("Memento", "11/10/2000")
     node.add(STestClass("Melvin and Howard", "19/09/1980"))
     node.add(STestClass("Melvin and Howard", "21/03/2007"))
     node.add(STestClass("Mellow Mud", "21/09/2016"))
     node.add(STestClass("Melody", "21/03/2007"))
Example #7
0
 def test_string(self, capsys):
     node = BSTNode(STestClass("Memento", "11/10/2000"))
     node.add(STestClass("Melvin and Howard", "19/09/1980"))
     node.add(STestClass("Mellow Mud", "21/09/2016"))
     node.add(STestClass("Melody", "21/03/2007"))
     print(node)
     capt = capsys.readouterr()
     assert capt.out == "Mellow Mud, Melody, Melvin and Howard, Memento\n"
Example #8
0
    def add(self, title, date, runtime):
        """Add a new movie to the library.

        Args:
            title - the title of the movie
            date - the date the movie was released
            runtime - the running time of the movie

        Returns:
            the movie file that was added, or None
        """
        add_movie = Movie(title, date, runtime)
        if self.bst is None:
            self.bst = BSTNode(add_movie)
            return add_movie
        return self.bst.add(add_movie)
Example #9
0
 def test_bst_node_init(self):
     """
     : Test the __init__ method of the BSTNode.
     """
     bst_node = BSTNode(5)
     self.assertEqual(bst_node.key, 5)
     self.assertEqual(bst_node.left, None)
     self.assertEqual(bst_node.right, None)
     self.assertEqual(bst_node.parent, None)
Example #10
0
 def random_tree(self, size=20, min_val=-100, max_val=100):
     """
     : Generate a Binary Search Tree of random integers. This tree is composed
     : of `BinarySearchTree` nodes strung together, rather than an actual instance
     : `BinarySearchTree`. Used for testing `BinarySearchTreeNode`'s methods.
     """
     values = [random.randint(min_val, max_val) for i in range(size)]
     minimum = min(values)
     maximum = max(values)
     index = random.randint(0, size - 1)
     # This creates a duplicate of whichever value lies at `index`.
     root = BSTNode(values[index])
     for val in values:
         _insert(root, BSTNode(val))
     obj = SimpleNamespace(
         root=root, minimum=minimum, maximum=maximum, values=values
     )
     return obj
Example #11
0
    def test_print_traversals(self):
        # WARNING:  Tests are for Print()
        # Debug calls to Print() in functions will cause failure

        stdout_ = sys.stdout  # Keep previous value
        sys.stdout = io.StringIO()

        self.bst = BSTNode(1)
        self.bst.insert(8)
        self.bst.insert(5)
        self.bst.insert(7)
        self.bst.insert(6)
        self.bst.insert(3)
        self.bst.insert(4)
        self.bst.insert(2)

        self.bst.in_order_print(self.bst)

        output = sys.stdout.getvalue()
        self.assertEqual(output, "1\n2\n3\n4\n5\n6\n7\n8\n")

        sys.stdout = io.StringIO()
        self.bst.bft_print(self.bst)
        output = sys.stdout.getvalue()
        self.assertTrue(output == "1\n8\n5\n3\n7\n2\n4\n6\n" or
                        output == "1\n8\n5\n7\n3\n6\n4\n2\n")

        sys.stdout = io.StringIO()
        self.bst.dft_print(self.bst)
        output = sys.stdout.getvalue()
        self.assertTrue(output == "1\n8\n5\n7\n6\n3\n4\n2\n" or
                        output == "1\n8\n5\n3\n2\n4\n7\n6\n")

        sys.stdout = io.StringIO()
        self.bst.pre_order_dft(self.bst)
        output = sys.stdout.getvalue()
        self.assertEqual(output, "1\n8\n5\n3\n2\n4\n7\n6\n")

        sys.stdout = io.StringIO()
        self.bst.post_order_dft(self.bst)
        output = sys.stdout.getvalue()
        self.assertEqual(output, "2\n4\n3\n6\n7\n5\n8\n1\n")

        sys.stdout = stdout_  # Restore stdout
Example #12
0
    def test_search(self):
        node = BSTNode(STestClass("A", "a"))
        node.add(STestClass("G", "g"))
        node.add(STestClass("H", "h"))
        node.add(STestClass("B", "b"))
        node.add(STestClass("Z", "z"))

        search_item = node.search_node(STestClass("C", "c"))
        assert search_item is None

        search_item = node.search(STestClass("H", "h"))
        assert search_item.full_str() == "H: h"
Example #13
0
 def consistent_tree(self):
     """
     : Generate a Binary Search Tree of consistent integers. This tree is composed
     : of `BinarySearchTree` nodes strung together, rather than an actual instance
     : `BinarySearchTree`. Used for testing `BinarySearchTreeNode`'s methods.
     """
     root_val = 6
     values = [-10, -6, 43, 65, 12, 43, 90, 3, 71, 3, -234, 94, 5]
     minimum = min(values)
     maximum = max(values)
     root = BSTNode(root_val)
     for val in values:
         _insert(root, BSTNode(val))
     # Append `root_val` to `values` for full list of tree's values.
     values.append(root_val)
     obj = SimpleNamespace(
         root=root, minimum=minimum, maximum=maximum, values=values
     )
     return obj
Example #14
0
    def test_search_node(self):
        node = BSTNode(STestClass("A", "a"))
        node.add(STestClass("G", "g"))
        node.add(STestClass("H", "h"))
        node.add(STestClass("B", "b"))
        node.add(STestClass("Z", "z"))

        search_node = node.search_node(STestClass("G", "g"))
        assert search_node._element.full_str() == "G: g"
Example #15
0
    def add(self, title, date, runtime):
        """ Add a new move to the library.

        Args:
            title - the title of the movie
            date - the date the movie was released
            runtime - the running time of the movie

        Returns:
            the movie file that was added, or None
        """
        # method body goes here
        # you need to create the Movie object, then add it to the BST,
        # take what is returned from that method, and then decide what to
        # return here.
        # Remember to handle the case where the bst is empty.
        # check to see if bst is None -
        movie = Movie(title, date, runtime)
        if self.bst is None:
            self.bst = BSTNode(movie)
            return movie
        return self.bst.add(movie)
 def test4_node_height_uneven_subtrees(self):
     """The height of a BSTNode with subtrees of uneven heights is the height of the taller subtree plus one. (0p)"""
     node = BSTNode(1)
     node.left = BSTNode(2)
     node.left.left = BSTNode(3)
     self.assertEqual(
         node.left.height(), 1,
         "Expected the height of a node with one child, which is a leaf, to be 1 but it was not."
     )
     node.right = BSTNode(4)
     self.assertEqual(
         node.right.height(), 0,
         "Expected the height of a leaf to be 0 but it was not.")
     self.assertEqual(
         node.height(),
         node.left.height() + 1,
         "Expected the height of a node with two children, left and right, of which right is a leaf and left has one child, which is a leaf, to be the height of left plus one but it was not."
     )
Example #17
0
    def test_create_node(self):
        root = BSTNode(0, None)
        self.assertTrue(root.left == None)
        self.assertTrue(root.right == None)
        self.assertTrue(root.value == 0)
        self.assertTrue(root.ref == None)

        node1 = BSTNode(1, root)
        self.assertTrue(node1.left == None)
        self.assertTrue(node1.right == None)
        self.assertTrue(node1.value == 1)
        self.assertTrue(node1.ref == root)

        root.right = node1
        logging.debug("BST root: %s" % str(root.to_list()))
        logging.debug("BST node1: %s" % str(node1.to_list()))
    def setUp(self):
        A = BSTNode(1, "A")
        B = BSTNode(3, "B")
        C = BSTNode(2, "C")

        B.left = C
        A.right = B

        #    A
        #     \
        #      B
        #     /
        #    C

        self.tree = AVL()
        self.nodes = (A, B, C)
Example #19
0
    def delete(self, value):
        # splay node to be deleted
        node = BSTNode.search(self, value)

        node.splay()

        # separate the left subtree, splay its successor to top
        node.left.parent = None
        node.left.successor().splay()

        # replace left subtree root with root
        node.value = node.left.value
        node.left = node.left.left
        # You don't have to replace the right child pointer: the sucessor
        # has no right child

        if node.left: node.left.parent = node
        if node.right: node.right.parent = node
Example #20
0
    def delete(self, value):
        # splay node to be deleted
        node = BSTNode.search(self, value)

        node.splay()

        # separate the left subtree, splay its successor to top
        node.left.parent = None
        node.left.successor().splay()
        
        # replace left subtree root with root
        node.value = node.left.value
        node.left = node.left.left
        # You don't have to replace the right child pointer: the sucessor  
        # has no right child

        if node.left: node.left.parent = node
        if node.right: node.right.parent = node
    def test5_find_one(self):
        """Calling find for a node which exists should return that node. (1p)"""
        node = BSTNode(2)
        node.left = BSTNode(1)
        node.right = BSTNode(3)
        self.tree.root = node

        for node in (node, node.left, node.right):
            found_node = self.tree.find(node.key)
            self.assertIs(
                found_node, node,
                "If {0!r} exists in tree, calling tree.find({1}) should return that node, not {2!r}"
                .format(node, node.key, found_node))
Example #22
0
class MovieLib:
    """A movie library.

    Implemented using a BST.
    """

    def __init__(self):
        """Initialise a movie library."""
        self.bst = None

    def __str__(self):
        """Return a string representation of the library.

        The string will be created by an in-order traversal.
        """
        if self.bst is not None:
            return str(self.bst)

    def size(self):
        """Return the number of movies in the library."""
        if self.bst is None:
            return 0
        return self.bst.size()

    def search(self, title):
        """Return Movie with matching title if there, or None.

        Args:
            title: a string representing a movie title.
        """
        if self.bst is not None:
            return self.bst.search(Movie(title))

    def add(self, title, date, runtime):
        """Add a new movie to the library.

        Args:
            title - the title of the movie
            date - the date the movie was released
            runtime - the running time of the movie

        Returns:
            the movie file that was added, or None
        """
        add_movie = Movie(title, date, runtime)
        if self.bst is None:
            self.bst = BSTNode(add_movie)
            return add_movie
        return self.bst.add(add_movie)

    def remove(self, title):
        """Remove and return the a movie object with the given title, if there.

        Args:
            title - the title of the movie to be removed
        """
        if self.bst is not None:
            removed = self.bst.remove(Movie(title))
            if self.bst.size() == 0:  # If tree is now empty
                self.bst = None  # Set reference to None
            return removed

    def _testadd():
        library = MovieLib()
        library.add("Memento", "11/10/2000", 113)
        print(str(library))
        print("> adding Melvin and Howard")
        library.add("Melvin and Howard", "19/09/1980", 95)
        print(str(library))
        print("> adding a second version of Melvin and Howard")
        library.add("Melvin and Howard", "21/03/2007", 112)
        print(str(library))
        print("> adding Mellow Mud")
        library.add("Mellow Mud", "21/09/2016", 92)
        print(str(library))
        print("> adding Melody")
        library.add("Melody", "21/03/2007", 113)
        print(str(library))
        return library

    def _test():
        library = MovieLib()
        library.add("B", "b", 1)
        print("Library:", library)
        print("adding", "A")
        library.add("A", "a", 1)
        print("Library:", library)
        print("removing", "A")
        library.remove("A")
        print("Library:", library)
        print("adding", "C")
        library.add("C", "c", 1)
        print("Library:", library)
        print("removing", "C")
        library.remove("C")
        print("Library:", library)
        print("adding", "F")
        library.add("F", "f", 1)
        print("Library:", library)
        print("removing", "B")
        library.remove("B")
        print("Library:", library)
        print("adding", "C")
        library.add("C", "c", 1)
        print("Library:", library)
        print("adding", "D")
        library.add("D", "d", 1)
        print("Library:", library)
        print("adding", "C")
        library.add("C", "c", 1)
        print("Library:", library)
        print("adding", "E")
        library.add("E", "e", 1)
        print("Library:", library)
        print("removing", "B")
        library.remove("B")
        print("Library:", library)
        print("removing", "D")
        library.remove("D")
        print("Library:", library)
        print("removing", "C")
        library.remove("C")
        print("Library:", library)
        print("removing", "E")
        library.remove("E")
        print("Library:", library)
        print("adding", "L")
        library.add("L", "l", 1)
        print("Library:", library)
        print("adding", "H")
        library.add("H", "h", 1)
        print("Library:", library)
        print("adding", "I")
        library.add("I", "i", 1)
        print("Library:", library)
        print("adding", "G")
        library.add("G", "g", 1)
        print("Library:", library)
        print("removing", "L")
        library.remove("L")
        print("Library:", library)
        print("removing", "H")
        library.remove("H")
        print("Library:", library)
        print("removing", "I")
        library.remove("I")
        print("Library:", library)
        print("removing", "G")
        library.remove("G")
        print("Library:", library)
import time
from bst import BSTNode

start_time = time.time()

f = open('names_1.txt', 'r')
names_1 = f.read().split("\n")  # List containing 10000 names
f.close()

f = open('names_2.txt', 'r')
names_2 = f.read().split("\n")  # List containing 10000 names
f.close()

duplicates = []  # Return the list of duplicates in this data structure
bst = BSTNode(names_1[0])
# Replace the nested for loops below with your improvements
for name_1 in names_1:
    bst.insert(name_1)

for name_2 in names_2:
    if bst.contains(name_2):
        duplicates.append(name_2)
# for name_1 in names_1:
#     for name_2 in names_2:
#         if name_1 == name_2:
#             duplicates.append(name_1)

end_time = time.time()
print (f"{len(duplicates)} duplicates:\n\n{', '.join(duplicates)}\n\n")
print (f"runtime: {end_time - start_time} seconds")
Example #24
0
f = open('names_2.txt', 'r')
names_2 = f.read().split("\n")  # List containing 10000 names
f.close()

duplicates = []  # Return the list of duplicates in this data structure

# Replace the nested for loops below with your improvements
# for name_1 in names_1:
#     for name_2 in names_2:
#         if name_1 == name_2:
#             duplicates.append(name_1)

# my implementation
# maybe use bst for one of the lists.
# method on bst to maybe compare the second method. 
bst = BSTNode(names_1[0])
for name in names_1:
    bst.insert(name)

for name in names_2:
    if bst.contains(name):
        duplicates.append(name)


end_time = time.time()
print (f"{len(duplicates)} duplicates:\n\n{', '.join(duplicates)}\n\n")
print (f"runtime: {end_time - start_time} seconds")

# runtime complexity of original answer
    # quadratic time or O(n squared) because for every value visited in names1.txt, we have to
    # visit every single value of names2.txt. thats every input of names1 multiplied by 
    return get_pair_with_sum_rec(orignl_root, node.left, sum) or \
           get_pair_with_sum_rec(orignl_root, node.right, sum)


def has_other_pair(root, this_node, rem):
    if not root:
        return
    if root.data == rem and this_node!=root:
        return root.data
    elif root.data < rem:
        return has_other_pair(root.right, this_node, rem)
    elif root.data > rem:
        return has_other_pair(root.left, this_node, rem)

if __name__ == "__main__":
    root = BSTNode(4)

    root.left = BSTNode(2)
    root.right = BSTNode(6)

    root.left.left = BSTNode(1)
    root.left.right = BSTNode(3)

    root.right.left = BSTNode(5)
    root.right.right = BSTNode(7)

    sum = 4
    for sum in xrange(1, 15):
        print get_pair_with_sum(root, sum),
        print get_pair_with_sum_rec(root, root, sum)
Example #26
0
    def splay_search(self, value):
        node = BSTNode.search(self, value)

        node.splay()

        return self # returns root, since node was moved to its place
    def test_is_bst_single_value(self):
        tree = BSTNode(0)

        self.assertTrue(is_BST(tree))
    def test_is_bst_none(self):
        tree = BSTNode(None)

        self.assertFalse(is_BST(tree))
    def test_is_not_bst(self):
        tree = BSTNode(3)
        tree.left_branch = BSTNode(2)
        tree.right_branch = BSTNode(1)

        self.assertFalse(is_BST(tree))
    def test_is_bst(self):
        tree = BSTNode(2)
        tree.left_branch = BSTNode(1)
        tree.right_branch = BSTNode(3)

        self.assertTrue(is_BST(tree))
 def test_bst_attributes(self):
     tree = BSTNode(1)
     self.assertEqual(tree.root, 1)
     self.assertEqual(tree.left_branch, None)
     self.assertEqual(tree.right_branch, None)
names_2 = f.read().split("\n")  # List containing 10000 names
f.close()

duplicates = []  # Return the list of duplicates in this data structure

# O (n^2)
# This Method is 5.24 Seconds
# Replace the nested for loops below with your improvements
# for name_1 in names_1:
#     for name_2 in names_2:
#         if name_1 == name_2:
#             duplicates.append(name_1)

# 0(n log n) ?
# BST Method Done in 0.11 Seconds
bst = BSTNode("")
# Build BST
for name_2 in names_2:
    bst.insert(name_2)

for name_1 in names_1:
    if bst.contains(name_1):
        duplicates.append(name_1)

end_time = time.time()
print(f"{len(duplicates)} duplicates:\n\n{', '.join(duplicates)}\n\n")
print(f"runtime: {end_time - start_time} seconds")

# ---------- Stretch Goal -----------
# Python has built-in tools that allow for a very efficient approach to this problem
# What's the best time you can accomplish?  Thare are no restrictions on techniques or data
Example #33
0
 def __init__(self, key):
     BSTNode.__init__(self, key)
     self.height = 0
Example #34
0
 def setUp(self):
     self.bst = BSTNode(5)