ESTRUTURAS DE DADOS (LEI, LM, LEE) PROGRAMAÇÃO III (LTSI) Universidade da Beira Interior, Departamento de Informática Hugo Pedro Proença, 2009/2010
Árvores Binárias AVL Tal como visto anteriormente, caso a inserção / remoção de elementos numa árvore binária não seja efectuada pela ordem conveniente, podem-se perder todas as vantagens associadas ao uso de estruturas não sequênciais: Exemplo: L 1 2 3 4
Árvores Binárias AVL Inserção na árvore dos elementos 1 2 3 4 A Inserção dos elementos 2 3 1 4 1 2 3 A 4 2 1 3 4
Árvores Binárias AVL Tal como visto anteriormente, caso a inserção / remoção de elementos numa árvore binária não seja efectuada pela ordem conveniente, podem-se perder todas as vantagens associadas ao uso de estruturas não sequênciais. As árvores binárias AVL definem uma forma de manuseamento de árvores binárias, tendo como objectivo mantê-las balanceadas. Alterações na inserção / remoção O nome AVL provém dos seus inventores: GM G.M. Adelson-Velskii e E.M. Landis, que publicaram o artigo: "An algorithm for the organization of information."
Árvores Binárias AVL Para cada nó é definido um factor de balanceamento, que é dado pela diferença entre o número de níveis dos ramos esquerdo e direito. Obtêm-se resultados semelhantes se forem simplesmente contados os nós do ramo esquerdo e direito. Caso a diferença seja 0, 1 ou -1 para todos os nós, considera-se que a árvore esstá balanceada. Se for diferente destes valores, é necessário recorrer a operações de balanceamento.
Árvores Binárias AVL: Exercício Implemente uma função que devolve o número de níveis de uma árvore binária. Protótipo: int niveis(nodoab *A);
Árvores Binárias AVL As operações de balanceamento consistem em operações de rotação (direita ou esquerda). Uma operação de rotação consiste em alterar a p ç ç estrutura da árvore sem alterar a ordem dos elementos.
Árvores Binárias AVL Pseudo-código para uma rotação à direita: Temp= Raiz.fe Raiz.fe = Temp.fd Temp.fd = Raiz Raiz = Temp Raiz 6 Temp 3 8 1 4 A rotaçao à esquerda é semelhante, trocando fd com fe no algoritmo acima descrito
Árvores Binárias AVL: Inserção Após cada inserção, é necessário verificar o estdo de balanceamento da árvore. Se todos os nós tiverem factores de balanceamento 0, 1 ou -1, a árvore considera-se balanceada. Caso algum nodo tenha factor de balanceamento diferente, será necessário aplicar operações de rotação. As rotações aplicar-se-ão às sub-árvores mínimas que não estão balanceadas (de baixo para cima).
Árvores Binárias AVL: Inserção Existem 4 casos possíveis: Esquerda e Direita-Esquerda Se o factor de balanceamento da raiz (R) é -2, a sub-árvore direita é mais profunda que a subárvore esquerda. Neste caso vai-se calcular o factor de balanceamento do seu filho direito. Se for -1, aplica-se uma rotação esquerda. Se for 1, é necessária uma operação de rotação dupla: rotação à direita (considerando D raiz) seguida de rotação à esquerda (R raiz). Direita e Esquerda-Direita Se o factor de balanceamento da raiz (R) é 2, a sub-árvore esquerda é mais profunda que a subárvore direita. Neste caso vai-se calcular o factor de balanceamento do seu filho esquerdo. Se for 1, aplica-se uma rotação direita. Se for -1, é necessária uma operação de rotação dupla: rotação à esquerda (L raiz) seguida de rotação à direita (R raiz).
Árvores Binárias AVL: Remoção Ao remover nós, é também necessário validar o estado da árvore. Se o nó é uma folha, removê-lo. Se não for, substituí-lo pelo maior elemento da sua sub-árvore esquerda (ou menor da sua sub-árvore direita) e remove-se aquele nodo. O nodo substituto terá no máximo ái uma subárvore. Após a remoção, verifica-se o estado de balanceamento desde o nó substituto até à raiz. Neste processo aplicam-se rotações sempre que necessário (similarmente ao processo de inserção).
Árvores Binárias AVL: Exercício NodoAB * insertavl(nodoab *A, NodoAB *nv); //Insere nv na árvore A. Deve ser garantido o balanceamento da árvore. NodoAB* removeavl(nodoab *A, NodoAB *del); //Remove o nodo del da árvore A e garante o balanceamento da árvore.