Esempio n. 1
0
    #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,
        )