#declaring empty array for i in range(0, len(n_array)): exp_res_array.append([None] * 5) print(exp_res_array) for j in range(0, len(n_array)): for k in range(0, 5): n = n_array[j] total_numbers = pow(5, n) arr = [None] * n random.seed(random.randint(0, 50)) #populating the array for i in range(0, n): randint = random.randint(0, total_numbers) arr[i] = randint #initiating and populating the bst tree = BST() for i in range(len(arr)): tree.insert(arr[i]) #getting the height of the tree print("For n: " + str(n) + ", tree height is " + str(tree.height())) exp_res_array[j][k] = tree.height() print("Exp results are as follows:") print(exp_res_array)
class Test4BSTProperty(unittest.TestCase): """ Test that the implemented BST methods do not break the binary search tree property. """ def setUp(self): self.tree = BST() def test1_smaller_values_go_left(self): """Adding values in sorted descending order creates internal nodes with only left children. (1p)""" # Insert nodes with keys 10, 9, 8, ... , 1 for key in range(10, 0, -1): self.tree.insert(key) # Starting from the root, traverse down towards the leaf, checking # both children of each node node = self.tree.root for key in range(10, 1, -1): self.assertEqual( key, node.key, "After inserting keys in range 10, 9, ... , 2, 1 and then iterating in that range, expected the keys of all the left nodes starting from the root follow this sequence, but a node {0} with the key {1} was found." .format(node, node.key)) # There should not be a right child self.assertIsNone( node.right, "Adding keys in order 10, 9, .. , 2, 1 should not create nodes with right children, but a node {0} with a right child {1} was found." .format(node, node.right)) # There should be a left child self.assertIsNotNone( node.left, "Adding keys in order 10, 9, .. , 2, 1 should only create nodes with left children, but a node {0} with no left child was found." .format(node)) # Go left to next node node = node.left # The last node is a leaf self.assertIsNone( node.left, "After adding nodes in range 10, 9, ... , 2, 1, the node with key 1 should be a leaf, but it had a left child {0}." .format(node.left)) self.assertIsNone( node.right, "After adding nodes in range 10, 9, ... , 1, the node with key 1 should be a leaf, but it had a right child {0}." .format(node.right)) def test2_larger_values_go_right(self): """Adding values in sorted ascending order creates internal nodes with only right children. (1p)""" # Insert nodes with keys 1, 2, ... , 10 for key in range(1, 11): self.tree.insert(key) # Starting from the root, traverse down towards the leaf, checking # both children of each node node = self.tree.root for key in range(1, 10): self.assertEqual( key, node.key, "After inserting keys in range 1, 2, ... , 9, 10 and then iterating in that range, expected the keys of all the right nodes starting from the root to follow this sequence, but a node {0} with the key {1} was found." .format(node, node.key)) # There should not be a left child self.assertIsNone( node.left, "Adding keys in order 1, 2, ... , 9, 10 should not create nodes with left children, but a node {0} with a left child {1} was found." .format(node, node.left)) # There should be a right child self.assertIsNotNone( node.right, "Adding keys in order 1, 2, ... , 9, 10 should only create nodes with right children, but a node {0} with no right child was found." .format(node)) # Go right to the next node node = node.right # The last node is a leaf self.assertIsNone( node.left, "After adding nodes in range 1, 2, ... , 9, 10, the node with key 10 should be a leaf, but it had a left child {0}." .format(node.left)) self.assertIsNone( node.right, "After adding nodes in range 1, 2, ... , 9, 10, the node with key 10 should be a leaf, but it had a left child {0}." .format(node.right)) def test3_inorder_traversal(self): """An inorder traversal visits all nodes in the tree. (1p)""" keys = random.sample(range(100), 20) inserted = set(self.tree.insert(key) for key in keys) visited = set(self.tree._visit_inorder(self.tree.root)) self.assertSetEqual( visited, inserted, "An inorder traversal should return all nodes which have been added to the tree.\n" + "_visit_inorder did not visit the nodes seen above although they were inserted into the tree." ) def test4_iter_tree_keys(self): """Iterating the tree yields the keys of the tree in sorted ascending order. (1p)""" keys = random.sample(range(100), 20) for key in keys: self.tree.insert(key) # Shorter form of [key for key in self.tree] # (which is possible because the class BST implements the method __iter__) visited = list(self.tree) # The returned values should be in sorted ascending order correct_order = sorted(keys) self.assertListEqual( visited, correct_order, "Calling __iter__ should return an iterator of the keys of the BST in sorted ascending order.\n" + "Note: the traversal method should not care in what order the nodes appear, if the insert method is implemented correctly, an inorder traversal will yield the keys in sorted order." ) def test5_height_complete_tree(self): """The height of a complete tree with n nodes is log_2(n+1) - 1. (1p)""" # Add keys so they form a complete tree keys = [50, 25, 75, 20, 30, 70, 80] for key in keys: self.tree.insert(key) tree_size = len(self.tree) added_count = len(keys) self.assertEqual( tree_size, added_count, "Adding {0} keys to an initially empty tree, calling len on the tree should return {0}, not {1}." .format(added_count, tree_size)) # math.log returns float self.assertAlmostEqual( float(self.tree.height()), math.log(len(keys) + 1, 2) - 1, )