def test_delete_single_element(self): tree = AVLTree([1]) tree.delete(1) self.assertNotIn(1, tree) self.assertFalse(tree) self.assertEqual(len(tree), 0)
def test_delete_leaf_node(self): tree = AVLTree([1, 2]) tree.delete(2) self.assertIn(1, tree) self.assertNotIn(2, tree) self.assertTrue(tree) self.assertEqual(len(tree), 1)
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_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)
class EventQueue: """ Implemented as AVLTree instead of MinHeap. """ def __init__(self): self.tree = AVLTree() self.size = 0 def insert_event(self, event: Point) -> bool: res = self.tree.insert(event) if res: self.size += 1 return res def get_nearest_event(self) -> Optional[Point]: return self.tree.min() def remove_event(self, event: Point) -> bool: res = self.tree.delete(event) if res: self.size -= 1 return res
class SweepLineStatus: """ Implemented with AVLTree. """ def __init__(self): self.tree = AVLTree() self.size = 0 def add_segment(self, segment: Segment) -> bool: res = self.tree.insert(segment) if res: self.size += 1 return res def remove_segment(self, segment: Segment) -> bool: res = self.tree.delete(segment) if res: self.size -= 1 return res def get_above_neighbor(self, segment: Segment) -> Optional[Segment]: current = self.tree.find(segment) assert (current is not None) above = self.tree.successor(current) if above is not None: return above.key return None def get_below_neighbor(self, segment: Segment) -> Optional[Segment]: current = self.tree.find(segment) assert (current is not None) below = self.tree.predecessor(current) if below is not None: return below.key return below def intersection_with_upper(self, segment: Segment) -> Optional[Point]: current = self.tree.find(segment) assert (current is not None) # Successor, because upper's y coordinate is bigger upper = self.tree.successor(current) if upper is None: return None else: point = calculate_intersection_point(upper.key, segment) if point is None: return None return point def intersection_with_lower(self, segment: Segment) -> Optional[Point]: current = self.tree.find(segment) assert (current is not None) lower = self.tree.predecessor(current) if lower is None: return None else: point = calculate_intersection_point(lower.key, segment) if point is None: return None return point def reach_intersection_of(self, upper: Segment, lower: Segment): upper_node = self.tree.find(upper) lower_node = self.tree.find(lower) temp_key = upper_node.key upper_node.key = lower_node.key lower_node.key = temp_key
def assert_entry_error(self, entries, entry_to_be_deleted): with self.assertRaises(KeyError) as context: tree = AVLTree(entries) tree.delete(entry_to_be_deleted) self.assertIn(f"entryError: {entry_to_be_deleted}", str(context.exception))
def test_avl_deletion(): """Tests that avl deletion maintains balance""" bintree = AVLTree() bintree.insert(10) bintree.insert(5) bintree.insert(15) bintree.insert(2) bintree.insert(7) bintree.insert(12) bintree.insert(30) bintree.insert(1) bintree.insert(11) bintree.insert(13) bintree.insert(35) bintree.insert(14) # 10 # / \ # 5 15 # / \ / \ # 2 7 12 30 # / / \ \ # 1 11 13 35 # \ # 14 # All inserted in an order such that no rotations occurred assert bintree.depth() == 5 assert bintree.balance() == -1 assert bintree.size() == 12 bintree.delete(15) # 10 # / \ # 5 14 # / \ / \ # 2 7 12 30 # / / \ \ # 1 11 13 35 # This is standard deletion, still in balance. # check that balance/depth update correctly assert bintree.balance() == 0 assert bintree.depth() == 4 assert bintree.size() == 11 assert bintree.rightchild.depth() == 3 assert bintree.rightchild.leftchild.depth() == 2 assert bintree.rightchild.leftchild.balance() == 0 # used to be -1 bintree.delete(7) # 10 # / \ # 5 14 # / / \ # 2 12 30 # / / \ \ # 1 11 13 35 # Now 5 is out of balance, rotate left up # 10 # / \ # 2 14 # / \ / \ # 1 5 12 30 # / \ \ # 11 13 35 assert bintree.leftchild.value == 2 assert bintree.balance() == -1 assert bintree.depth() == 4 assert bintree.leftchild.depth() == 2 assert bintree.leftchild.rightchild.depth() == 1 bintree.delete(10) # 11 # / \ # 2 14 # / \ / \ # 1 5 12 30 # \ \ # 13 35 # Just normal deletion bintree.delete(11) # 12 # / \ # 2 14 # / \ / \ # 1 5 13 30 # \ # 35 # Just normal deletion bintree.delete(12) # 13 # / \ # 2 14 # / \ \ # 1 5 30 # \ # 35 # Now 14 is out of balance, rotate 30 up # 13 # / \ # 2 30 # / \ / \ # 1 5 14 35 assert bintree.depth() == 3 assert bintree.balance() == 0 assert bintree.value == 13 assert bintree.leftchild.value == 2 assert bintree.rightchild.value == 30 assert bintree.leftchild.depth() == 2 assert bintree.rightchild.depth() == 2
from avl_tree import AVLTree tree = AVLTree() for i in range(0,14): tree.insert(i) tree.delete(12) print(tree.to_string())
def main(): print "-:=Test AVL trees=:-" if (len(sys.argv) != 6): print "Use: ./test_avl.py <words_file_name> <meanings_file_name> <number_of_insertions> <number_of_search> <number of delete>" sys.exit(0) else: words_file_name = sys.argv[1] meanings_file_name = sys.argv[2] print "Words file: " + words_file_name + "\nMeanings file: " + meanings_file_name inserts = int(sys.argv[3]) searchs = int(sys.argv[4]) deletes = int(sys.argv[5]) sys.stdout.write("Inserts: %s\t" % inserts) sys.stdout.write("Searchs: %s\t" % searchs) sys.stdout.write("Deletes: %s\n" % deletes) f = open(words_file_name, "r") f2 = open(meanings_file_name, "r") """ INSERTS PART """ avl = AVLTree(node=AVLNode()) #print "Is an empty tree: ", avl.is_empty() #print "Tree height: ", avl.height() t0_1 = time.time() t0 = time.strftime('%s') words = [] for i in range(0, inserts): word = f.readline() #print "word read: " , word.strip() definition = f2.readline() #print "meaning read: ", definition.strip() if not word: break if not definition: break words.append(word.strip()) print "words: ", words avl.modify(word.strip(), definition.strip()) t1 = time.strftime('%s') print "words: ", words if inserts > 0: t1_1 = time.time() t_insert = t1_1 - t0_1 print "Insertion process ends successfully! -> time ", t_insert print "" """ SEARCH PART """ if searchs > 0: t0 = time.time() for s in range(0, searchs): #word = f.readline() word = words[random.randint(0, len(words) - 1)] avl.search(word) t1 = time.time() t_search = t1 - t0 print "Search operations done! -> time ", t_search print "" """ DELETE PART """ if deletes > 0 and deletes <= inserts: t0 = time.time() for s in range(0, deletes): word = words[random.randint(0, len(words) - 1)] print 'word to delete: ', word avl.delete(word) t1 = time.time() t_delete = t1 - t0 print "Delete operations done! -> time ", t_delete print "" # Closing file descriptors f.close() f2.close() print "Resultant tree:" avl.draw_tree() print "Height tree: ", avl.height()
from avl_tree import AVLTree import random avl = AVLTree() root = None nums = list(range(1, 10)) for num in nums: root = avl.insert(root, num) print("Percurso em Largura (por nivel) depois da inserção -") avl.percurso_nivel(root) print() key = nums[3] root = avl.delete(root, key) # pre_order Traversal print("Percurso em Largura (por nivel) depois da remoção -") avl.percurso_nivel(root) print()