def test_delete_entry_make_tree_unbalanced(self): entries = [5, 3, 8, 2, 4, 7, 11, 1, 6, 10, 12, 9] tree = AVLTree(entries) entry_to_be_deleted = 4 tree.delete(entry_to_be_deleted) expected_order = (8, 5, 11, 2, 7, 10, 12, 1, 3, 6, 9) self.assertNotIn(entry_to_be_deleted, tree) self.assertTupleEqual(tuple(tree.traverse('bfs')), expected_order)
def test_delete_entry_but_tree_remains_balanced(self): entries = [10, 5, 11, 3, 7, 15] tree = AVLTree(entries) entry_to_be_deleted = 10 tree.delete(entry_to_be_deleted) expected_order = (7, 5, 11, 3, 15) self.assertNotIn(entry_to_be_deleted, tree) self.assertTupleEqual(tuple(tree.traverse('bfs')), expected_order)
def test_empty_traversal(self): tree = AVLTree() d = { 'preorder': (), 'inorder': (), 'postorder': (), 'bfs': (), } for order, expected_value in d.items(): with self.subTest(f"test {order}"): self.assertTupleEqual(tuple(tree.traverse(order)), expected_value)
def test_delete_entries_in_a_row(self): entries = [2, 1, 4, 3, 5] tree = AVLTree(entries) tree.delete(1) self.assertNotIn(1, tree) self.assertTupleEqual(tuple(tree.traverse('bfs')), (4, 2, 5, 3)) tree.delete(2) self.assertNotIn(2, tree) self.assertTupleEqual(tuple(tree.traverse('bfs')), (4, 3, 5)) tree.delete(3) self.assertNotIn(3, tree) self.assertTupleEqual(tuple(tree.traverse('bfs')), (4, 5)) tree.delete(4) self.assertNotIn(4, tree) self.assertTupleEqual(tuple(tree.traverse('bfs')), (5, )) tree.delete(5) self.assertNotIn(5, tree) self.assertTupleEqual(tuple(tree.traverse('bfs')), ()) self.assertFalse(tree)
def test_initialize_tree_from_sequence(self): import math entries = [1, 2, 3, 4, 5, 6, 7] tree = AVLTree(entries) expected_order = (4, 2, 6, 1, 3, 5, 7) with self.subTest( f"bfs traversal must be have this order {expected_order}."): self.assertTupleEqual(tuple(tree.traverse('bfs')), expected_order) with self.subTest(f"tree must have {len(entries)} entries."): self.assertEqual(len(tree), len(entries)) with self.subTest( f"tree must have {math.ceil(math.log2(len(entries)))} height." ): self.assertEqual(tree.height, math.ceil(math.log2(len(entries))))
def test_pred(self): import random random.seed(7477) entries = get_random_entries() tree = AVLTree(entries) with self.subTest(f"test pred found"): pred, prev = None, None for entry in tree.traverse(): try: pred = tree.pred(entry) except KeyError: self.assertIsNone(prev) self.assertEqual(prev, pred) prev = entry with self.assertRaises(KeyError) as context: tree.pred(1000000) self.assertIn("Predecessor of 1000000 not found.", str(context.exception))
def test_traversal(self): tree = AVLTree() tree.insert(20) tree.insert(10) tree.insert(25) tree.insert(23) tree.insert(29) tree.insert(30) d = { 'preorder': (25, 20, 10, 23, 29, 30), 'inorder': (10, 20, 23, 25, 29, 30), 'postorder': (10, 23, 20, 30, 29, 25), 'bfs': (25, 20, 29, 10, 23, 30), } for order, expected_value in d.items(): with self.subTest(f"test {order}"): self.assertTupleEqual(tuple(tree.traverse(order)), expected_value)