def test_num_children(self): tree = LinkedBinaryTree() tree._add_root(0) root = tree.root() tree._add_right(root, 1) tree._add_left(root, 2) self.assertEqual(2, tree.num_children(root))
def test_parent(self): tree = LinkedBinaryTree() tree._add_root(0) root = tree.root() tree._add_left(root, 1) left = tree.left(root) parent = tree.parent(left) self.assertEqual(parent, root)
def test__add_right(self): tree = LinkedBinaryTree() tree._add_root(0) root = tree.root() tree._add_right(root, 1) right = tree.right(root) self.assertEqual(1, right.element())
def test__add_left(self): tree = LinkedBinaryTree() tree._add_root(0) root = tree.root() tree._add_left(root, 1) left = tree.left(root) self.assertEqual(1, left.element())
def _attach(self, p, t_list): """ Attach trees storing in t_list to the external Position p in the order with t_list itself. As a side effect, trees in t_list will be set to empty. :raise : TypeError if trees in t_list do not match type of this tree :raise : ValueError if Position p is invalid or not external. """ if not t_list: return if self._binary_tree.left(p) is None: t1 = t_list.pop(0) if not type(self) is type(t1): raise TypeError('Tree types must match') t2 = LinkedBinaryTree() self._binary_tree._force_attach(p, t1._binary_tree, t2) left = self._binary_tree.left(p) for t2 in t_list: if type(t2) is not type(self): raise TypeError('Tree types must match') t1 = LinkedBinaryTree() self._binary_tree._force_attach(left, t1, t2._binary_tree) return
def test_ParenthesizeTour(self): t = LinkedBinaryTree() root = t._add_root("Data Structure") left = t._add_left(root, "Tree") t._add_right(root, "List") t._add_left(left, "Array Tree") right = t._add_right(left, "Linked Tree") t._add_left(right, "Binary Tree") t._add_right(right, "RB Tree") et = ParenthesizeTour(t) et.execute()
def test__delete(self): tree = LinkedBinaryTree() tree._add_root(0) root = tree.root() tree._add_right(root, 1) tree._delete(root) root = tree.root() self.assertEqual(root.element(), 1) self.assertTrue(tree.is_root(root))
def test__replace(self): tree = LinkedBinaryTree() tree._add_root(0) root = tree.root() tree._add_right(root, 1) tree._replace(root, 6) root = tree.root() self.assertEqual(root.element(), 6) right = tree.right(root) self.assertEqual(right.element(), 1)
def test__add_root(self): tree = LinkedBinaryTree() tree._add_root(0) root = tree.root() self.assertEqual(0, root.element())
def test_inorder(self): tree = LinkedBinaryTree() root = tree._add_root(0) left = tree._add_left(root, 1) right = tree._add_right(root, 2) tree._add_left(left, 3) tree._add_right(left, 4) tree._add_left(right, 5) tree._add_right(right, 6) visited = tree.inorder() elements = [v.element() for v in visited] self.assertEqual([3, 1, 4, 0, 5, 2, 6], elements)
def test_breadth_first(self): tree = LinkedBinaryTree() root = tree._add_root(0) left = tree._add_left(root, 1) right = tree._add_right(root, 2) tree._add_left(left, 3) tree._add_right(left, 4) tree._add_left(right, 5) tree._add_right(right, 6) visited = tree.breadth_first() elements = [v.element() for v in visited] self.assertEqual([0, 1, 2, 3, 4, 5, 6], elements)
def test__attach(self): tree = LinkedBinaryTree() tree._add_root(0) root = tree.root() tree._add_right(root, 1) right = tree.right(root) tree1 = LinkedBinaryTree() tree1._add_root(2) tree2 = LinkedBinaryTree() tree2._add_root(3) tree._attach(right, tree1, tree2) right = tree.right(root) e1 = tree.left(right) e2 = tree.right(right) self.assertEqual(2, e1.element()) self.assertEqual(3, e2.element())
class Tree(object): """ General tree implementation adapting a binary tree.""" # constructor def __init__(self): self._binary_tree = LinkedBinaryTree() # public accessor def root(self): """ Return Position representing the tree's root (or None if empty).""" return self._binary_tree.root() def parent(self, p): """ Return the Position of p's parent (or None if p is root).""" father = self._binary_tree.parent(p) child = p while self._binary_tree.right(father) is child: child = father father = self._binary_tree.parent(child) return father def num_children(self, p): """ Return the number of children of Position p.""" count = 0 if self._binary_tree.left(p): child = self._binary_tree.left(p) while child: count += 1 child = self._binary_tree.right(child) return count def children(self, p): """ Generate an iteration of Positions representing p's children.""" if self._binary_tree.left(p): child = self._binary_tree.left(p) while child: yield child child = self._binary_tree.right(child) def __len__(self): """ Return the total number of elements in the tree.""" return len(self._binary_tree) def __str__(self): """ str representation of linked binary tree.""" s = '' for item in self: s += str(item) return s def is_root(self, p): """ Return True if Position p represents the root of the tree.""" return self.root() == p def is_leaf(self, p): """ Return True if Position p does not have any children.""" return self.num_children(p) == 0 def is_empty(self): """ Return True if the tree is empty.""" return len(self) == 0 def depth(self, p): """ Return the number of levels separating Position p from the root.""" if self.is_root(p): return 0 elif self._binary_tree.right(self.parent(p)) == p: return self.depth(self.parent(p)) else: return 1 + self.depth(self.parent(p)) def _height(self, p): """ Return the height of the subtree rooted at Position p.""" if self.is_leaf(p): return 0 else: return 1 + max(self._height(c) for c in self.children(p)) def height(self, p=None): if p is None: p = self.root() return self._height(p) def __iter__(self): """ Generate an iteration of the tree's elements.""" for p in self.positions(): yield p.element() def positions(self): """ Generate an iteration of the tree's positions.""" return self.preorder() # return entire preorder iteration def preorder(self): """ Generate a preorder iteration of positions in the tree.""" return self._binary_tree.preorder() def postorder(self): """ Generate a postorder iteration of positions in the tree.""" return self._binary_tree.inorder() def breadthfirst(self): """ Generate a breadth-first iteration of the positions of the tree.""" return self._binary_tree.breadthfirst() # nonpublic mutators def _add_root(self, e): """ Place element e at the root of an empty tree and return new Position. Raise ValueError if tree nonempty. """ return self._binary_tree._add_root(e) def _add_child(self, p, e): """ Create a new child for Position p, storing element e.""" left = self._binary_tree.left(p) if left is not None: return self._binary_tree._add_right(left, e) else: return self._binary_tree._add_left(p, e) def _replace(self, p, e): """ Replace the element at position p with e, and return old element.""" return self._binary_tree._replace(p, e) def _delete(self, p): """Delete the node at Position p, and replace it with its child, if any. :return : the element that had been stored at Position p. :raise : ValueError if Position p is invalid or p has two children. """ if self.num_children(p) > 1: raise ValueError('Position has more than one child') elif self.num_children(p) == 0: self._binary_tree._delete(p) else: child = self._binary_tree.left(p)._node if p == self.root(): self._binary_tree._root = p._node else: parent = self.parent(p)._node parent._left = child child._parent = parent self._binary_tree._size -= 1 p._node._parent = p._node return p.element() def _attach(self, p, t_list): """ Attach trees storing in t_list to the external Position p in the order with t_list itself. As a side effect, trees in t_list will be set to empty. :raise : TypeError if trees in t_list do not match type of this tree :raise : ValueError if Position p is invalid or not external. """ if not t_list: return if self._binary_tree.left(p) is None: t1 = t_list.pop(0) if not type(self) is type(t1): raise TypeError('Tree types must match') t2 = LinkedBinaryTree() self._binary_tree._force_attach(p, t1._binary_tree, t2) left = self._binary_tree.left(p) for t2 in t_list: if type(t2) is not type(self): raise TypeError('Tree types must match') t1 = LinkedBinaryTree() self._binary_tree._force_attach(left, t1, t2._binary_tree) return
def test_PreorderPrintIndentedTour(self): t = LinkedBinaryTree() root = t._add_root("Data Structure") left = t._add_left(root, "Tree") t._add_right(root, "List") t._add_left(left, "Array Tree") right = t._add_right(left, "Linked Tree") t._add_left(right, "Binary Tree") t._add_right(right, "RB Tree") et = PreorderPrintIndentedTour(t) et.execute()
def test__validate(self): tree = LinkedBinaryTree() tree._add_root(0)
def disk_space(tree: Tree, position: Tree.Position): """ :param tree: tree :param position: position :return: the total disk space for subtree of tree rooted at position """ total = 0 if tree.is_leaf(position) and isinstance(position.element(), File): total = position.element().size for c in tree.children(position): total += disk_space(tree, c) return total t = LinkedBinaryTree() root = t._add_root("Data Structure") left = t._add_left(root, "Tree") t._add_right(root, "List") t._add_left(left, "Array Tree") right = t._add_right(left, "Linked Tree") t._add_left(right, "Binary Tree") t._add_right(right, "RB Tree") # parenthesis(t, root) disk = LinkedBinaryTree()
def __init__(self): self._binary_tree = LinkedBinaryTree()