Introdução a árvores AVL · 2012-08-23 · 100 80 130 200 1 0 0 0 120 100 150 80 110 130 200 0 0...
Transcript of Introdução a árvores AVL · 2012-08-23 · 100 80 130 200 1 0 0 0 120 100 150 80 110 130 200 0 0...
IntroduIntrodução a árvores AVLção a árvores AVL
Prof. Ernesto Lindstaedt
Definição Definição
O nome AVL vem dos seus criadores Adelson O nome AVL vem dos seus criadores Adelson Velsky e Landis (1962); Velsky e Landis (1962);
Uma ABP Uma ABP TT é denominada é denominada AVLAVL se:se:•• Para todos nós de Para todos nós de TT, as alturas de suas duas , as alturas de suas duas
subsub--árvores diferem árvores diferem no máximo em uma no máximo em uma unidade;unidade;
Uma ABP é Uma ABP é completamente balanceadacompletamente balanceadaquando a distância média dos nós até a raiz for quando a distância média dos nós até a raiz for mínima.mínima.
Definição Definição Balanceamento EstáticoBalanceamento EstáticoEste balanceamento consiste em, depois de um Este balanceamento consiste em, depois de um certo tempo de uso da árvore, destruir sua certo tempo de uso da árvore, destruir sua estrutura, guardando suas informações em uma estrutura, guardando suas informações em uma lista ordenada e reconstruílista ordenada e reconstruí--la de forma la de forma balanceada. balanceada.
Balanceamento DinâmicoBalanceamento DinâmicoTem por objetivo reajustar os nós de uma árvore Tem por objetivo reajustar os nós de uma árvore sempre que uma inserção ou remoção provocar sempre que uma inserção ou remoção provocar desbalanceamento.desbalanceamento.
Definição Definição Como saber se a árvore está Como saber se a árvore está desbalanceada desbalanceada ??•• Verificando se existe algum nó “desregulado”.Verificando se existe algum nó “desregulado”.
Como saber se um nodo está Como saber se um nodo está desregulado desregulado ? ? •• SubtraindoSubtraindo--se as alturas das suas subse as alturas das suas sub--árvores. árvores.
Por questões de Por questões de eficiênciaeficiência, estas diferenças são , estas diferenças são prépré--calculadas e armazenadas nos nós calculadas e armazenadas nos nós correspondentes, sendo atualizadas durante as correspondentes, sendo atualizadas durante as operações.operações.
AVL AVL –– Fator de BalanceamentoFator de BalanceamentoPossíveis valores de diferença para cada nó em Possíveis valores de diferença para cada nó em uma árvore balanceada: uma árvore balanceada: --11, , 00, , 11..
Fator de Balanceamento (FB) de cada nó da Fator de Balanceamento (FB) de cada nó da árvoreárvore•• FB(p)FB(p) = h(sae(p)) = h(sae(p)) –– h(sad(p)) :h(sad(p)) :
h = alturah = alturap = nóp = nósae = subsae = sub--árvore à esquerdaárvore à esquerdasad = subsad = sub--árvore à direitaárvore à direita
Em uma árvore binária balanceada todos os FB Em uma árvore binária balanceada todos os FB de todos os nós estão no intervalo de todos os nós estão no intervalo --1 1 ≤≤ FB FB ≤≤ 1.1.
AVLAVL
Exemplo de uma ABP não AVLExemplo de uma ABP não AVLInserção: 4, 1, 3, 6, 5, 2 e 7
4
1 6
3
2
75
1
-2
1
0
0
0 0
Fator de BalanceamentoEx.: Nó Raiz
FB(“4”) = 3 – 2 FB(“4”) = 1
AVL AVL –– VantagemVantagemA vantagem de uma árvore balanceada com A vantagem de uma árvore balanceada com relação a uma degenerada está em sua relação a uma degenerada está em sua eficiência;eficiência;
Ex.: numa árvore binária degenerada de 10.000 Ex.: numa árvore binária degenerada de 10.000 nós são necessárias, em média, 5.000 nós são necessárias, em média, 5.000 comparações (semelhança com arrays ordenados comparações (semelhança com arrays ordenados e listas encadeadas);e listas encadeadas);
Numa árvore balanceada com o mesmo número Numa árvore balanceada com o mesmo número de nós essa média reduzde nós essa média reduz--se a 14 comparações.se a 14 comparações.
AVL AVL –– OperaçõesOperaçõesA inserção ou remoção de um nó em uma árvore A inserção ou remoção de um nó em uma árvore AVL AVL podepode ou ou nãonão provocar seu provocar seu desbalanceamento;desbalanceamento;
Se a árvore AVL ficar desbalanceada, a Se a árvore AVL ficar desbalanceada, a restauração do seu balanceamento é realizado restauração do seu balanceamento é realizado através de através de ROTAÇÕESROTAÇÕES..
Rotação Dupla:Rotação à EsquerdaRotação à Direita
Rotação Simples:Rotação à EsquerdaRotação à Direita
AVL AVL –– Classe Nodo Classe Nodo public class public class AvlNodeAvlNode {{
protected int height; protected int height; protected int key;protected int key;protected AvlNode left, right;protected AvlNode left, right;
public AvlNode ( int theElement ) {public AvlNode ( int theElement ) {this( theElement, null, null );this( theElement, null, null );
}}
public AvlNode ( int theElement, AvlNode lt, AvlNode rt public AvlNode ( int theElement, AvlNode lt, AvlNode rt ) ) {{
key = theElement;key = theElement;left = lt;left = lt;right = rt;right = rt;height = 0;height = 0;
}}}}
AVL AVL –– Rotação Simples à DireitaRotação Simples à DireitaToda vez que uma subToda vez que uma sub--árvore fica com um árvore fica com um fator:fator:•• positivopositivo e sua sube sua sub--áárvore da esquerda tambrvore da esquerda tambéém m
tem um fator tem um fator positivopositivo
120
110 150
100
80
130 200
1
0
0
0
120
100 150
80 110 130 200
0
0
00
0
0 0
2
01
AVL AVL –– Rotação Simples à DireitaRotação Simples à Direita
k2
k1
x y
z
Nó k2 é a raiz de transformação
X, Y e Z são subárvores (vazias ou não)
AVL AVL –– Classe InicialClasse Inicial
public class AvlTree {private AvlNode root = null;
/** Retorna a altura da árvore */private static int height ( AvlNode t ) {
return t == null ? 0 : t.height;}
/** Retorna o maior valor ente lhs e rhs. */private static int max ( int lhs, int rhs ) {
return lhs > rhs ? lhs : rhs;}
/** Retorna o fator de balanceamento da árvore com raiz t */private int getFactor (AvlNode t) {
return height( t.left ) - height( t.right );}
AVL AVL –– Rotação Simples à DireitaRotação Simples à Direita
k2
k1
x y
z
k1
k2
y z
xRotação Direita
private static AvlNode doRightRotation( AvlNode k2 ) {AvlNode k1 = k2.left;k2.left = k1.right;k1.right = k2;k2.height = max( height( k2.left ), height( k2.right ) ) + 1;k1.height = max( height( k1.left ), k2.height ) + 1;return k1;
}
AVL AVL –– Rotação Simples à DireitaRotação Simples à Direita
42
15 88
6 27
1
Incluir 4
42
15 88
6 27
2
01
1 0
40
0 0
0 0
AVL AVL –– Rotação Simples à DireitaRotação Simples à Direita
RotaçãoDireita
42
15 88
6 27
15
6 42
4 27
0
01
0 0880
Ajustado!
2
1 0
1 0
40
AVL AVL –– Rotação Simples à EsquerdaRotação Simples à EsquerdaToda vez que uma subToda vez que uma sub--árvore fica com um árvore fica com um fator:fator:•• negativonegativo e sua sube sua sub--áárvore da direita tambrvore da direita tambéém tem m tem
um fator um fator negativo negativo 120
100 130
150
200
80 110
Rotação Esquerda
-1
0
0 0
0
-2
-1
120
100 150
80 110 130 200
Completamente BalanceadaFB = 0
AVL AVL –– Rotação Simples à EsquerdaRotação Simples à Esquerdak2
k1
x y
z
k1
k2
y z
x
Rotação Esquerda
private static AvlNode doLeftRotation( AvlNode k1 ) {AvlNode k2 = k1.right;k1.right = k2.left;k2.left = k1;k1.height = max( height( k1.left ), height( k1.right ) ) + 1;k2.height = max( height( k2.right ), k1.height ) + 1;return k2;
}
AVL AVL –– Rotação Simples à EsquerdaRotação Simples à Esquerda
42
15 88
9467
-1
00
0 0
Incluir 90
42
15 88
9467
-2
-10
0 1
900
AVL AVL –– Rotação Simples à EsquerdaRotação Simples à Esquerda
88
42 94
9067
0
Ajustado!
42
15 88
9467
-2
RotaçãoEsquerda0 -1 0 1
0150 1 00
900
AVL AVL –– Rotação Dupla à DireitaRotação Dupla à DireitaToda vez que uma subToda vez que uma sub--árvore fica com um árvore fica com um fator:fator:•• positivopositivo e sua sube sua sub--áárvore da esquerda tem um rvore da esquerda tem um
fator fator negativonegativo120
110 150
80
100
130 200
Rotação DuplaDireita
1
2
-1
0 0
0
0
AVL AVL –– Rotação Dupla à Rotação Dupla à DireitaDireita
DIREITA
ESQUERDA
120
110 150
80
100
130 200
120
110 150
100
80
130 200
120
100 150
80 110 130 200
AVL AVL –– Rotação Dupla à DireitaRotação Dupla à Direitak3
k1
a
b
d
k2
k3
c d
Rotação Esquerda
k2
c
k1
a b
k3
k2
c
a
d
k1
b
RotaçãoDireita
1
2
AVL AVL –– Rotação Dupla à DireitaRotação Dupla à Direita
Rotação DuplaDireita
k3
k1
a
b
d
k2
c
k2
k3
c d
k1
a b
private static AvlNode doDoubleRightRotation( AvlNode k3 ) {
k3.left = doLeftRotation( k3.left );return doRightRotation( k3 );
}
AVL AVL –– Rotação Dupla à DireitaRotação Dupla à Direita
42
15 88
276
Incluir 34
42
15 88
276
2
0-1
-10
34 0
1
0 0
0 0
AVL AVL –– Rotação Dupla à DireitaRotação Dupla à Direita
Rotação DuplaDireita
PASSO 1Rotação Esquerda
42
15 88
276
242
27 88
3415
2
01
1
6
0
-1 0
0 -1
34 00
AVL AVL –– Rotação Dupla à DireitaRotação Dupla à DireitaPASSO 2
Rotação DireitaRotação
DuplaDireita 27
15 42
34
42
27 88
3415
02
1 01 0
6 0 08801 0
60
AVL AVL –– Rotação Dupla à EsquerdaRotação Dupla à EsquerdaToda vez que uma subToda vez que uma sub--árvore fica com um árvore fica com um fator:fator:•• negativonegativo e sua sube sua sub--áárvore da direita tem um fator rvore da direita tem um fator
positivopositivo120
100 130
200
150
80 110
Rotação Dupla
Esquerda
-1
-2
1
00
0
0
AVL AVL –– Rotação Dupla à EsquerdaRotação Dupla à Esquerda
DIREITA
120
100 130
200
150
80 110
ESQUERDA
120
100 130
150
200
80 110
120
100 150
80 110 130 200
AVL AVL –– Rotação Dupla à EsquerdaRotação Dupla à Esquerdak1
k3
d
b
a
k2
c
ROTAÇÃO DIREITA
k1
k2
b
c
a
k3
dk2
k3
c d
k1
a b
ROTAÇÃOESQUERDA
AVL AVL –– Rotação Dupla à EsquerdaRotação Dupla à Esquerda
k1
k3
d
b
a
k2
c
Rotação Dupla
Esquerda
k2
k3
c d
k1
a b
private static AvlNode doDoubleLeftRotation (AvlNode k1) {k1.right = doRightRotation( k1.right );return doLeftRotation( k1 );
}
AVL AVL –– InserçãoInserção• Percorre-se a árvore verificando se a chave já existe ou não
• Em caso positivo, encerra a tentativa de inserção• Caso contrário, a busca encontra o local correto de inserção
do novo nó
• Verifica-se se a inclusão tornará a árvore desbalanceada• Em caso negativo, o processo termina• Caso contrário, deve-se efetuar o balanceamento da árvore
• Descobre-se qual a operação de rotação a ser executada
• Executa-se a rotação
AVL AVL –– Método para inserçãoMétodo para inserçãoprivate AvlNode insert (int x, AvlNode t) {
if( t == null ) t = new AvlNode( x, null, null );else if( x<t.key ) t.left = insert( x, t.left );else if( x>t.key) t.right = insert( x, t.right );if ( getFactor(t) == 2 ) {
if (getFactor (t.left)>0) t = doRightRotation( t );else t = doDoubleRightRotation( t );
}else if ( getFactor(t) == -2 ) {
if ( getFactor(t.right)<0 ) t = doLeftRotation( t );else t = doDoubleLeftRotation( t );
}t.height = max( height( t.left ), height( t.right ) ) + 1;return t;
}
public boolean insert (int x) {// se nó já existe, retorna falseroot = insert (x, root);return true;
}
AVL AVL –– ExclusãoExclusão• Caso parecido com as inclusões;• No entanto, nem sempre se consegue solucionar com
uma única rotação;• Remover elemento e retornar do pai do nó removido
até a raiz, verificando se cada nó do caminho precisa ser balanceado.
AVL AVL –– ExclusãoExclusão32
16
8
48
24 40 56
28 36 44 52 60
58 62
Excluindo 8
-1
-1
0
-1
-1
0
0 0
-1
0 0
0 0
0
AVL AVL –– ExclusãoExclusão32
16 48
24 40 56
28 36 44 52 60
58 62
0
-1
-2
-1
-1
-1
0
0
000
0
rotação simples à esquerda
0
AVL AVL –– ExclusãoExclusão32
24 48
16 40 5628
36 44 52 60
58 62
00
0
0 0
0 0
00
-10
-1
rotação simples à esquerda
volta recursivamente até a raiz, balanceando todos os nós que se encontrarem desbalanceados.
AVL AVL –– ExclusãoExclusão
32
24
48
16
40
56
28 36 44
52 60
58 620 0
0
0 0
0
0
00
00
-1
0
AVL AVL -- ComplexidadeComplexidade• Uma única reestruturação é O(1)
• usando uma árvore binária implementada com estrutura ligada
• Pesquisa é O(log n)• altura de árvore é O(log n), não necessita reestruturação
• Inserir é O(log n)• busca inicial é O(log n)• reestruturação para manter balanceamento é O(log n)
• Remover é O(log n)• busca inicial é O(log n)• reestruturação para manter balanceamento é O(log n)