def test_items_level_order_with_3_strings(self): # Create a complete binary search tree of 3 strings in level-order items = ['B', 'A', 'C'] tree = BinarySearchTree(items) print("dem trees") print(tree) # Ensure the level-order traversal of tree items is ordered correctly print("dis order is popin") print(tree.items_level_order()) assert tree.items_level_order() == ['B', 'A', 'C']
def test_items_level_order_with_7_numbers(self): # Create a complete binary search tree of 7 items in level-order items = [4, 2, 6, 1, 3, 5, 7] tree = BinarySearchTree(items) # Ensure the level-order traversal of tree items is ordered correctly assert tree.items_level_order() == [4, 2, 6, 1, 3, 5, 7]
class TreeSet(object): """Class for sets implemented with binary trees""" def __init__(self, items=None): """Initialize a new Set""" self.tree = BinarySearchTree(items) # self.size = self.tree.size def __repr__(self): """Return a string representation of this set""" items = ['({!r})'.format(item) for item in self.tree.items_in_order()] return ', '.join(items) def __iter__(self): """Allow the set to be iterated over (i.e. in for loops)""" return iter([value for value in self.tree.items_level_order()]) def __eq__(self, other): """Allow sets to be compared to other sets""" return self.tree.items_in_order() == other.tree.items_in_order() @property def size(self): """Use tree size property""" return self.tree.size def contains(self, item): """Return a boolean indicating whether item is in this set Best case time complexity: O(1) if item is in the tree root Worst case: O(logn) if item is a leaf """ return self.tree.search(item) is not None def add(self, item): """Add the item to the set if not present Best case time complexity: O(1) if tree is empty Worst case: O(n) if tree is poorly balanced """ if not self.contains(item): self.tree.insert(item) def remove(self, item): """Remove element from this set, if present, or else raise KeyError Best case time complexity: O(1) if item is in the tree root Worst case: O(logn) if item isn't there """ if not self.contains(item): raise KeyError("Item not found") else: self.tree.delete(item) def union(self, other_set): """Return a new set that is the union of this set and other_set Best and worst case time complexity: O(n+m), where n is the size of self, and m is the size of other_set, because every item has to be accounted for """ new_set = TreeSet(self) for item in other_set: new_set.add(item) return new_set def intersection(self, other_set): """Return a new set that is the intersection of this and other_set Best and worst case time complexity: O(m) where m is the size of other_set, because it iterates over the other set. """ new_set = TreeSet() for item in other_set: if self.contains(item): new_set.add(item) return new_set def difference(self, other_set): """Return a new set that is the difference of this set and other_set Best and worst case time complexity: O(n + logm) where n is the size of self, and m is the size of other_set, because it iterates over self and checks if other_set contains the items """ new_set = TreeSet() for item in self: if not other_set.contains(item): new_set.add(item) return new_set def is_subset(self, other_set): """Return a boolean indicating if other_set is a subset of this Best case time complexity: O(1) if other_set is larger than self Worst case: O(m) where m is the size of other_set, as it has to iterate over each element of it """ if other_set.size > self.size: return False for item in other_set: if not self.contains(item): return False return True
def test_delete(self): items = [4, 2, 6, 1, 3, 5, 7] # Balanced tree tree = BinarySearchTree(items) assert tree.items_level_order() == [4, 2, 6, 1, 3, 5, 7] assert tree.size == 7 # Delete leaves tree.delete(7) assert tree.items_level_order() == [4, 2, 6, 1, 3, 5] assert tree.size == 6 tree.delete(1) assert tree.items_level_order() == [4, 2, 6, 3, 5] assert tree.size == 5 # Delete nodes with one branch tree.delete(2) assert tree.items_level_order() == [4, 3, 6, 5] assert tree.size == 4 tree.delete(6) assert tree.items_level_order() == [4, 3, 5] assert tree.size == 3 # Reset tree = BinarySearchTree(items) assert tree.items_level_order() == [4, 2, 6, 1, 3, 5, 7] assert tree.size == 7 # Delete double branch tree.delete(2) assert tree.items_level_order() == [4, 1, 6, 3, 5, 7] assert tree.size == 6 tree.delete(6) assert tree.items_level_order() == [4, 1, 5, 3, 7] assert tree.size == 5 # Reset tree = BinarySearchTree(items) assert tree.items_level_order() == [4, 2, 6, 1, 3, 5, 7] assert tree.size == 7 # Delete root tree.delete(4) print(tree.items_level_order()) assert tree.items_level_order() == [3, 2, 6, 1, 5, 7] # Larger tree items = [8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15] tree = BinarySearchTree(items) tree.delete(8) assert tree.items_level_order() == [ 7, 4, 12, 2, 6, 10, 14, 1, 3, 5, 9, 11, 13, 15 ] tree.delete(7) print(tree.items_level_order()) assert tree.items_level_order() == [ 6, 4, 12, 2, 5, 10, 14, 1, 3, 9, 11, 13, 15 ] tree.delete(6) print(tree.items_level_order()) assert tree.items_level_order() == [ 5, 4, 12, 2, 10, 14, 1, 3, 9, 11, 13, 15 ]