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
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)
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')
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
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"))
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"
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 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)
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
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
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"
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
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"
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." )
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)
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))
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")
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)
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
def __init__(self, key): BSTNode.__init__(self, key) self.height = 0
def setUp(self): self.bst = BSTNode(5)