def test_initialization_with_right_node(self): right_node = BinaryTree.Node(1) node = BinaryTree.Node(0, right=right_node) assert node.key == 0 assert node.right == right_node assert node.right.key == 1 assert not node.right._left assert not node.right._right assert not node.left
def test_initialization_with_left_and_right_node(self): left_node = BinaryTree.Node(1) right_node = BinaryTree.Node(2) node = BinaryTree.Node(0, left_node, right_node) assert node.key == 0 assert node.left == left_node assert node.left.key == 1 assert not node.left._left assert not node.left._right assert node.right == right_node assert node.right.key == 2 assert not node.right._left assert not node.right._right
def _get_key_and_item(item): if isinstance(item, BinaryTree.Node): key = item.key else: key = item item = BinaryTree.Node(key) return key, item
def delete(self, key): node = self.search(key) if not node: return False if node.is_leaf(): if node is self.root: self.root = None else: node.remove() return True if node.left and not node.right: if node is self.root: self.root = node.left else: node.replace(node.left) return True if node.right and not node.left: if node is self.root: self.root = node.right else: node.replace(node.right) return True if node.right and node.left: successor = node.in_order_successor() new_node = BinaryTree.Node(successor.key, node.left, node.right) if node is self.root: self.root = new_node else: node.replace(new_node) successor.remove() return True raise Exception("Should never get here.")
def test_build_binary_tree(self): """ Build a tree of the following structure: j <-- root / \ f k / \ \ a h z <-- leaves """ node = BinaryTree.Node j_node = node("j") f_node = node("f") k_node = node("k") a_node = node("a") h_node = node("h") z_node = node("z") tree = BinaryTree(j_node) j_node.left = f_node j_node.right = k_node f_node.left = a_node f_node.right = h_node k_node.right = z_node assert tree.root.key == "j" assert tree.root._left.key == "f" assert tree.root._right.key == "k" assert tree.root._left._left.key == "a" assert tree.root._left._left.is_leaf() assert tree.root._left._right.key == "h" assert tree.root._left._right.is_leaf() assert tree.root._right._right.key == "z" assert tree.root._right._right.is_leaf()
def test_double_rotate_right_left(self): """ Test the double rotation with right-rotate followed by left-rotate. The starting tree is on the left, the result is on the right: 1 1 2 \ \ / \ 3 ===> 2 ===> 1 3 / \ 2 3 """ root = BinaryTree.Node(1) root.right = BinaryTree.Node(3) root.right.left = BinaryTree.Node(2) tree = BinaryTree(root) tree.double_rotate_right_left(tree.root) assert tree.root.key == 2 assert tree.root.left.key == 1 assert tree.root.right.key == 3
def test_double_rotate_left_right(self): """ Test a double rotation with a left-rotate followed by a right-rotate. The starting tree is on the left, the result is on the right: 3 3 2 / / / \ 1 ===> 2 ===> 1 3 \ / 2 1 """ root = BinaryTree.Node(3) root.left = BinaryTree.Node(1) root.left.right = BinaryTree.Node(2) tree = BinaryTree(root) tree.double_rotate_left_right(tree.root) assert tree.root.key == 2 assert tree.root.left.key == 1 assert tree.root.right.key == 3
class TestBinaryTreeSingleRotation: """ A rotation of a BinaryTree changes the structure of the tree without changing the order of the elements. The operation is used to balance a BinarySearchTree. """ def setup_method(self): """ Build a tree with this structure 10 / \ 5 15 / \ / \ 3 8 12 18 / \ / \ 1 4 16 20 :return: """ root = BinaryTree.Node(10) root.left = BinaryTree.Node(5) root.left.left = BinaryTree.Node(3) root.left.right = BinaryTree.Node(8) root.left.left.left = BinaryTree.Node(1) root.left.left.right = BinaryTree.Node(4) root.right = BinaryTree.Node(15) root.right.left = BinaryTree.Node(12) root.right.right = BinaryTree.Node(18) root.right.right.left = BinaryTree.Node(16) root.right.right.right = BinaryTree.Node(20) self.tree = BinaryTree(root) def test_right_rotate(self): """ Test rotating the subtree starting at 5 to the right. i.e.: 5 3 / \ / \ 3 8 ===> 1 5 / \ / \ 1 4 4 8 """ self.tree.right_rotate(self.tree.root.left) assert self.tree.root.key == 10 assert self.tree.root.left.key == 3 assert self.tree.root.left.left.key == 1 assert self.tree.root.left.right.key == 5 assert self.tree.root.left.right.left.key == 4 assert self.tree.root.left.right.right.key == 8 def test_left_rotate(self): """ Test rotating the subtree starting at 15 to the left. i.e.: 15 18 / \ / \ 12 18 ===> 15 20 / \ / \ 16 20 12 16 """ self.tree.left_rotate(self.tree.root.right) assert self.tree.root.key == 10 assert self.tree.root.right.key == 18 assert self.tree.root.right.left.key == 15 assert self.tree.root.right.right.key == 20 assert self.tree.root.right.left.left.key == 12 assert self.tree.root.right.left.right.key == 16
def test_initialization_with_data(self): node = BinaryTree.Node(0) assert node.key == 0 assert not node.left assert not node.right
def test_right_must_be_a_node(self): with raises(BinaryTree.Node.ChildMustBeNodeException): BinaryTree.Node(0, right=0)
def test_root_must_be_node(self): with raises(BinaryTree.RootMustBeBinaryTreeNodeException): BinaryTree(0)
def test_access_root_data(self): root = BinaryTree.Node(0) tree = BinaryTree(root) assert tree.root.key == 0
def test_initialized_with_root_not_empty(self): root = BinaryTree.Node(0) tree = BinaryTree(root) assert not tree.empty()
def test_node_with_neither_left_nor_right_is_leaf(self): node = BinaryTree.Node(0) assert node.is_leaf()
def test_node_with_right_but_not_left_is_not_leaf(self): right_node = BinaryTree.Node(2) node = BinaryTree.Node(0, right=right_node) assert not node.is_leaf()
def test_node_with_left_but_not_right_is_not_leaf(self): left_node = BinaryTree.Node(1) node = BinaryTree.Node(0, left_node) assert not node.is_leaf()
def setup_method(self): """ Build a tree with this structure 10 / \ 5 15 / \ / \ 3 8 12 18 / \ / \ 1 4 16 20 :return: """ root = BinaryTree.Node(10) root.left = BinaryTree.Node(5) root.left.left = BinaryTree.Node(3) root.left.right = BinaryTree.Node(8) root.left.left.left = BinaryTree.Node(1) root.left.left.right = BinaryTree.Node(4) root.right = BinaryTree.Node(15) root.right.left = BinaryTree.Node(12) root.right.right = BinaryTree.Node(18) root.right.right.left = BinaryTree.Node(16) root.right.right.right = BinaryTree.Node(20) self.tree = BinaryTree(root)
def test_initialization(self): tree = BinaryTree() assert isinstance(tree, BinaryTree)
def test_initialization(self): node = BinaryTree.Node() assert isinstance(node, BinaryTree.Node) assert not node.key assert not node.left assert not node.right
def test_initialized_tree_is_empty(self): tree = BinaryTree() assert tree.empty()