def test_delete_reattach(): """Removing the root from a 2-depth V should reattach nodes correctly.""" tree = AVLTree([3, 2, 4, 1, 5]) tree.delete(3) assert 3 not in tree assert pre_order(tree) == [2, 1, 4, 5] assert_avl_invariants(tree.root)
def test_delete_trivial(insert, delete, expected): """Tests deletion of root/leaf nodes requiring no rotation.""" tree = AVLTree(insert) tree.delete(delete) assert delete not in tree assert pre_order(tree) == expected assert_avl_invariants(tree.root)
def test_delete_single_rotation(insert, delete, expected): """Tests deletion resulting in a single rotation.""" tree = AVLTree(insert) tree.delete(delete) assert delete not in tree assert pre_order(tree) == expected assert_avl_invariants(tree.root)
def test_delete_attach_without_rotation(insert, deletes, expected): """Tests selective pruning of nodes and reattaching them to parents.""" tree = AVLTree(insert) for key in deletes: tree.delete(key) assert key not in tree assert pre_order(tree) == expected assert_avl_invariants(tree.root)
def test_delete_rotation_under_root(insert, delete): tree = AVLTree(insert) tree.delete(delete) assert delete not in tree expected = sorted(insert) expected.remove(delete) assert in_order(tree) == expected assert_avl_invariants(tree.root)
def test_delete_double_rotation(): """Tests deletion resulting in a double rotation.""" tree = AVLTree([16, 8, 24, 4, 12, 20, 28, 2, 6, 10, 32, 1, 3]) tree.delete(20) assert 20 not in tree assert tree.root.value == 8 assert tree.root.left.value == 4 assert tree.root.right.value == 16 assert_avl_invariants(tree.root)
def test_two_way_rotations_with_subtree_at_pivot(insert, delete): """Deletion causes a LR or RL rotation and the new subtree root has children.""" tree = AVLTree(insert) tree.delete(delete) assert delete not in tree expected = sorted(insert) expected.remove(delete) assert in_order(tree) == expected assert_avl_invariants(tree.root)
def test_double_insert_exception(): tree = AVLTree([5]) with pytest.raises(ValueError): tree.insert(5)
def test_instantiate_from_string(): tree = AVLTree("abc") assert "a" in tree assert "b" in tree assert "c" in tree
def test_instantiate_from_iter(): tree = AVLTree(range(1, 3)) assert 1 in tree assert 2 in tree
def test_instantiate_from_list(): tree = AVLTree([1, 2]) assert 1 in tree assert 2 in tree
def test_tree_insert(): tree = AVLTree() tree.insert(5) assert 5 in tree
def test_rank_ordered_traversal(rank_order): tree = AVLTree(rank_order) assert list(breadth_first(tree)) == rank_order
def test_empty_tree_traversal(traverser): assert list(traverser(AVLTree())) == []
def test_basic_rotations(insert, expected): """Tests basic tree rotations and resulting balance.""" tree = AVLTree(insert) assert_avl_invariants(tree.root) assert pre_order(tree) == expected
def test_delete_nonexisting(): """Tests deletion of nonexisting key raises KeyError.""" tree = AVLTree() with pytest.raises(KeyError): tree.delete(2)
def test_delete_root(): """Tests deletion of singular root node.""" tree = AVLTree([1]) tree.delete(1) assert 1 not in tree assert tree.root is None
def test_double_rotation(): tree = AVLTree([5, 4, 3, 2, 1]) assert_avl_invariants(tree.root) assert pre_order(tree) == [4, 2, 1, 3, 5]
@pytest.fixture(params=[depth_first_inorder, ordered_iterative]) def in_order_traverser(request): """Returns an in-order traverser.""" return request.param @pytest.mark.parametrize( "traverser", [breadth_first, depth_first_inorder, ordered_iterative]) def test_empty_tree_traversal(traverser): assert list(traverser(AVLTree())) == [] @pytest.mark.parametrize( "tree, expected", [ (AVLTree([4, 2, 6, 1, 3, 5, 7]), [1, 2, 3, 4, 5, 6, 7]), (AVLTree([4, 2, 6, 1, 5, 7]), [1, 2, 4, 5, 6, 7]), (AVLTree([4, 2, 6, 3, 5, 7]), [2, 3, 4, 5, 6, 7]), (AVLTree(range(30, 100)), list(range(30, 100))), ], ) def test_ordered_traversal(in_order_traverser, tree, expected): assert list(in_order_traverser(tree)) == expected @pytest.mark.parametrize( "tree, child, expected", [ (AVLTree([4, 2, 6, 1, 3]), "left", [1, 2, 3]), (AVLTree([4, 2, 6, 5, 7]), "right", [5, 6, 7]), (AVLTree([4, 2, 6, 1]), "left", [1, 2]),