def test_should_build_avl_tree_with_height_five(self): tree = Tree() for i in range(32): tree.insert(i) assert_that(tree.root.height, equal_to(5)) assert_that(tree.root, equal_to(15))
def test_should_remove_right_node_with_only_left_child_in_avl_tree(self): tree = Tree() for i in range(7, 3, -1): tree.insert(i) tree.delete(5) assert_that(tree.root.height, equal_to(1)) assert_that(tree.root, equal_to(6)) assert_that(tree.root.left, equal_to(4)) assert_that(tree.root.right, equal_to(7))
def test_should_build_avl_tree(self): tree = Tree() for i in range(5): tree.insert(i) assert_that(tree.root.height, equal_to(2)) assert_that(tree.root, equal_to(1)) assert_that(tree.root.left, equal_to(0)) assert_that(tree.root.right, equal_to(3)) assert_that(tree.root.right.left, equal_to(2)) assert_that(tree.root.right.right, equal_to(4))
def test_should_remove_right_node_with_only_right_child_in_avl_tree(self): tree = Tree() for i in range(6): tree.insert(i) tree.delete(4) assert_that(tree.root.height, equal_to(2)) assert_that(tree.root, equal_to(3)) assert_that(tree.root.left, equal_to(1)) assert_that(tree.root.left.left, equal_to(0)) assert_that(tree.root.left.right, equal_to(2)) assert_that(tree.root.right, equal_to(5))
def test_should_remove_right_leaf_in_avl_tree(self): tree = Tree() for i in range(5): tree.insert(i) tree.delete(4) assert_that(tree.root.height, equal_to(2)) assert_that(tree.root, equal_to(1)) assert_that(tree.root.left, equal_to(0)) assert_that(tree.root.right, equal_to(3)) assert_that(tree.root.right.left, equal_to(2)) assert_that(tree.root.right.right, equal_to(None))
def test_should_remove_node_with_both_children_in_avl_tree(self): tree = Tree() for i in range(1, 8): tree.insert(i) tree.delete(6) assert_that(tree.root.height, equal_to(2)) assert_that(tree.root, equal_to(4)) assert_that(tree.root.left, equal_to(2)) assert_that(tree.root.left.left, equal_to(1)) assert_that(tree.root.left.right, equal_to(3)) assert_that(tree.root.right, equal_to(7)) assert_that(tree.root.right.left, equal_to(5)) assert_that(tree.root.right.right, equal_to(None))
def test_should_find_min_and_delete_all(self): tree = Tree() tree.insert(0) tree.insert(1) tree.insert(2) for _ in range(3): tree.delete_min() assert_that(tree.root, equal_to(None))
def __call__(self, nodes): """Cria uma árvore AVL com todos os nós e suas distâncias iniciais em O(v log v) Percorre a lista de nós em O(v) e insere cada nó com sua distância inicial na árvore em O(log v). Args: nodes (list): lista de nós do grafo Returns: self AVL """ self.__tree = Tree() self.__nodes = len(nodes) self.__distances = [None] * (max(nodes) + 1) for node in nodes: self.__distances[node] = math.inf self.__tree.insert(DistanceNode(node, math.inf)) return self
def test_should_find_and_delete(self): tree = Tree() tree.insert(0) tree.insert(1) tree.insert(2) removed = tree.find_min().delete() assert_that(removed, equal_to(0)) assert_that(tree.root.height, equal_to(1)) assert_that(tree.root, equal_to(1)) assert_that(tree.root.left, equal_to(None)) assert_that(tree.root.right, equal_to(2))
class AVL(datastructs.DijkstraDistance): def __call__(self, nodes): """Cria uma árvore AVL com todos os nós e suas distâncias iniciais em O(v log v) Percorre a lista de nós em O(v) e insere cada nó com sua distância inicial na árvore em O(log v). Args: nodes (list): lista de nós do grafo Returns: self AVL """ self.__tree = Tree() self.__nodes = len(nodes) self.__distances = [None] * (max(nodes) + 1) for node in nodes: self.__distances[node] = math.inf self.__tree.insert(DistanceNode(node, math.inf)) return self def pop(self): """Encontra e remove da arvore o nó com menor distância. O(lg v) Percorre a árvore, comparando lg v nós até encontrar o nó mais a esquerda, que por definição é o menor. Então remove o nó da árvore e retorna juntamento com sua distância. Returns: int, int: nó de menor distância e sua respectiva distância. """ self.__nodes -= 1 popped = self.__tree.delete_min() return popped.key.vertex, popped.key.distance def update(self, node, distance): """Atualiza a distância de um nó. Encontra o nó em O(lg v), remove o nó em O(lg v) e reinsere o nó atualizado em O(lg v) Args: node (int): O nó a ser atualizado distance (int): A nova distância """ self.__tree.delete(DistanceNode(node, self.__distances[node])) self.__tree.insert(DistanceNode(node, distance)) self.__distances[node] = distance def has_nodes_to_visit(self): """bool: Retorna verdadeiro se existe algum nó que ainda não foi visitado. Do contrário, falso.""" return self.__nodes > 0 def value(self, node): """Retorna a distância de um dado nó em O(1). Args: node (int): O nó Returns: int: distancia """ return self.__distances[node] @property def values(self): """Cria e retorna um dict com todos os nós e suas distâncias atualizadas em O(v). Returns: dict(no: distancia) """ return dict([(k, v) for k, v in enumerate(self.__distances) if v is not None])