Programação II Prof. Mateus Raeder Universidade do Vale do Rio dos Sinos - São Leopoldo -...
-
Upload
natan-florio -
Category
Documents
-
view
221 -
download
0
Transcript of Programação II Prof. Mateus Raeder Universidade do Vale do Rio dos Sinos - São Leopoldo -...
Programação II
Prof. Mateus Raeder
Universidade do Vale do Rio dos Sinos- São Leopoldo -
Transparências baseadas nos originais da profa. Renata Galante da II/UFRGS
Programação II – Prof. Mateus Raeder
Árvores Binárias de Pesquisa • Apresentam uma relação de ordem• A ordem é definida pela chave• Operações:
– inserir– consultar– excluir
500
300 800
150 400 900600
Programação II – Prof. Mateus Raeder
Problemas com ABPExemplo:
– Inserção: 10, 5, 15, 20, 25, 30, 35– Inserção: 1, 13, 24, 27, 56
10
5 15
20
25
30
35
Programação II – Prof. Mateus Raeder
Problemas com ABP• Desbalanceamento progressivo• Exemplo:
– inserção: 1, 13, 24, 27, 56
1
13
24
27
56
Solução:- Árvores AVL
(Árvores Balanceadas)
Programação II – Prof. Mateus Raeder
Balanceamento de Árvores• Distribuição equilibrada dos nós
– otimizar as operações de consulta– diminuir o número médio de comparações
• Distribuição– uniforme – não uniforme
• chaves mais solicitadas mais perto da raiz
Programação II – Prof. Mateus Raeder
Por Frequência• Por frequência de acesso
– Pressupõe distribuição não uniforme de acessos
500
800400
900600
550
50%
12% 25%
4% 5%
4%
Balanceamento por distribuiçãode acessos!
Programação II – Prof. Mateus Raeder
Árvores AVL
• Adelson-Velskii e Landis (1962)• Fator de um nó
– Fator = (altura_subarv_esq) – (altura_subarv_dir)
Programação II – Prof. Mateus Raeder
Árvores AVL• Relembrando:
– NÍVEL de um nó: número de nós entre ele e a raiz (contando ele próprio)
– ALTURA (ou Profundidade) da árvore: é o seu maior nível
A
B C
D E
F G
Nível 1
Nível 2
Nível 3
Nível 4
ALTURA = 4
Programação II – Prof. Mateus Raeder
Árvores AVL
• Adelson-Velskii e Landis (1962)• Fator de um nó
– Fator = (altura_subarv_esq) – (altura_subarv_dir)
Qual o fator dos nós da árvore ao lado?
A
B C
D E
G H
I J
Programação II – Prof. Mateus Raeder
Árvores AVL
• Uma árvore AVL é uma árvore binária de pesquisa (ABP) construída de tal modo que a altura de sua subárvore direita difere da altura da subárvore esquerda de no máximo 1– ou seja, o fator de nó deve ser -1, 0, 1.
• Também chamada de árvore balanceada.
A
B C
D E
G H
I J
+3
-2
0 -1
0 0
00Não é árvore AVL
0
Programação II – Prof. Mateus Raeder
Exercício:Verifique quais das ABP são AVL:
130
150100
20012080
110
120
130100
20011080
150
Programação II – Prof. Mateus Raeder
Exercício: RespostaVerifique quais das ABP são AVL:
130
150100
20012080
110
120
130100
20011080
150
+1
-1 -1
00
0 0
0 0 +1
-20
-1
AVLNão AVL
+1
Programação II – Prof. Mateus Raeder
ExercícioVerifique quais das ABP são AVL:
42
8815
63276 94
20 7157
42
8815
63276 94
42
8815
6327
20 7157
Programação II – Prof. Mateus Raeder
Exercício: RespostaVerifique quais das ABP são AVL:
42
8815
63276 94
20 7157
42
8815
63276 94
42
8815
6327
20 7157
0
0
0 0 0 0
0AVL: completamente
balanceada
000
0+1
-10
0 0
0 0 0
0
+1 -2
0
+2
AVL Não AVL
+1
Programação II – Prof. Mateus Raeder
• por exemplo: INSERÇÃO• deve ser preservada a propriedade AVL
Reestruturar a árvore
Operações
Programação II – Prof. Mateus Raeder
Operações• Como manter uma árvore AVL sempre
balanceada após uma inserção ou exclusão?– Através de uma operação de ROTAÇÃO
• Característica da operação– preserva a ordem das chaves– basta uma execução da operação de rotação
para tornar a árvore AVL novamente
Programação II – Prof. Mateus Raeder
AVLNodepublic class AvlNode {
protected int height; protected int key;
protected AvlNode left, right;
public AvlNode ( int theElement ) { this( theElement, null, null ); }
public AvlNode ( int theElement, AvlNode lt, AvlNode rt ) { key = theElement; left = lt; right = rt; height = 0; }
public int getHeight() {return height;
}
public void setHeight(int height) {this.height = height;
}
Programação II – Prof. Mateus Raeder
AVLNodepublic int getKey() {
return key;}
public void setKey(int key) {this.key = key;
}
public AvlNode getLeft() {return left;
}
public void setLeft(AvlNode left) {this.left = left;
}
public AvlNode getRight() {return right;
}
public void setRight(AvlNode right) {this.right = right;
}}
Programação II – Prof. Mateus Raeder
Rotação Dupla• à direita • à esquerda
Rotação Simples• à direita • à esquerda
Balanceamento de Árvore AVL com Rotação
Programação II – Prof. Mateus Raeder
Rotação Simples DIREITA
• Toda vez que uma subárvore fica com um fator:– positivo e sua subárvore da esquerda
também tem um fator positivo
ROTAÇÃO SIMPLES À DIREITA
Programação II – Prof. Mateus Raeder
Rotação Direita
120
110 150
100
80
130 200
Programação II – Prof. Mateus Raeder
120
110 150
100
80
130 200
+1
0
00
+2
+1
0
Rotação Direita
Programação II – Prof. Mateus Raeder
120
110 150
100
80
130 200
+1
0
00
+2
+1
0
Rotação Direita ?
Rotação Direita
Programação II – Prof. Mateus Raeder
120
110 Rotação Direita150
100
80
130 200
120
100 150
80 110 130 200
+1
+2
+1
0
0 0
0
0 0 0 0
00
0
Rotação Direita
Programação II – Prof. Mateus Raeder
Balanceamento de Árvore AVL com Rotação
k2
k1
x y
z
Nó k2 é a raiz de transformação
X, Y e Z são subárvores (vazias ou não)
Rotação Simples• à direita
Programação II – Prof. Mateus Raeder
Métodos auxiliares public class AvlTree { private AvlNode root = null; /** Retorna a altura da árvore */ private static int height ( AvlNode t ) { if(t == null)
return 0;return t.height;//return t == null ? 0 : t.height;
} /** Retorna o maior valor ente lhs e rhs. */ private static int max ( int lhs, int rhs ) {
if(lhs > rhs) return lhs;return 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 ); }
Programação II – Prof. Mateus Raeder
k2
k1
x y
z
k1
k2
y z
x
Rotação Direita
Rotaçã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;}
Programação II – Prof. Mateus Raeder
42
15 88
6 27
+1
00
0 0
Incluir 4
42
15 88
6 27
+2
0+1
+1 0
40
Rotação Direita
Programação II – Prof. Mateus Raeder
RotaçãoDireita
42
15 88
6 27
+2
0+1
+1 0
40
15
6 42
4 27
0
0+1
0 0880
Ajustado!Rotação Direita
Programação II – Prof. Mateus Raeder
Rotação Simples ESQUERDA• Toda vez que uma subárvore fica com
um fator:– negativo e sua subárvore da direita
também tem um fator negativo
ROTAÇÃO SIMPLES À ESQUERDA
Programação II – Prof. Mateus Raeder
120
100 130
150
200
80 110
-1
0
0 0
0
-2
-1
Rotação Simples ESQUERDA
Programação II – Prof. Mateus Raeder
120
100 130
150
200
80 110
Rotação Esquerda ?
-1
0
0 0
0
-2
-1
Rotação Simples ESQUERDA
Programação II – Prof. Mateus Raeder
120
100 130
150
200
80 110
Rotação Esquerda
120
100 150
80 110 130 200
Rotação Simples ESQUERDA
Programação II – Prof. Mateus Raeder
k2
k1
x y
z
k1
k2
y z
x
Rotação Esquerda
Rotação Simples ESQUERDA
Programação II – Prof. Mateus Raeder
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;}
Rotação Simples ESQUERDA
k2
k1
x y
z
k1
k2
y z
x
Rotação Esquerda
Programação II – Prof. Mateus Raeder
42
15 88
9467
-1
00
0 0
Incluir 90
42
15 88
9467
-2
-10
0 1
900
Rotação Simples ESQUERDA
Programação II – Prof. Mateus Raeder
88
42 94
9067
0
+10
0 015042
15 88
9467
-2
-10
0 1
900
RotaçãoEsquerda
Ajustado!
Rotação Simples ESQUERDA
Programação II – Prof. Mateus Raeder
Rotação Dupla à Direita• Toda vez que uma subárvore fica com
um fator:– positivo e sua subárvore da esquerda tem
um fator negativo
ROTAÇÃO DUPLA À DIREITA
Programação II – Prof. Mateus Raeder
120
110 150
80
100
130 200
+1
+2
-1
0
0 0
0
Rotação Dupla à Direita
Programação II – Prof. Mateus Raeder
120
110 150
80
100
130 200
Rotação DuplaDireita ?
+1
+2
-1
0
0 0
0
Rotação Dupla à Direita
Programação II – Prof. Mateus Raeder
DIREITA
ESQUERDA
120
110 150
80
100
130 200
120
110 150
100
80
130 200
120
100 150
80 110 130 200
Rotação Dupla à Direita
Programação II – Prof. Mateus Raeder
k3
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
Rotação Dupla à Direita
1
2
Programação II – Prof. Mateus Raeder
Rotação DuplaDireita
Rotação Dupla à Direita
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 );}
Programação II – Prof. Mateus Raeder
42
15 88
276
+1
00
00
Incluir 34
42
15 88
276
+2
0-1
-10
34 0
Rotação Dupla à Direita
Programação II – Prof. Mateus Raeder
42
15 88
276
+2
0-1
-10
34 0
Rotação DuplaDireita
0
PASSO 1Rotação Esquerda
42
27 88
3415
+2
0+1
+1
6
0
Rotação Dupla à Direita
Programação II – Prof. Mateus Raeder
Rotação DuplaDireita
PASSO 2Rotação Direita
42
27 88
3415
+2
0+1
+1
0 6
0
27
15 42
34
0
0+1
06 0 880
Rotação Dupla à Direita
Programação II – Prof. Mateus Raeder
Rotação Dupla ESQUERDA• Toda vez que uma subárvore fica com um
fator:– negativo e sua subárvore da direita tem um fator
positivo
ROTAÇÃO DUPLA À ESQUERDA
Programação II – Prof. Mateus Raeder
120
100 130
200
150
80 110
-1
-2
+1
0
00
0
Rotação Dupla ESQUERDA
Programação II – Prof. Mateus Raeder
120
100 130
200
150
80 110
Rotação Dupla
Esquerda ?-1
-2
+1
0
00
0
Rotação Dupla ESQUERDA
Programação II – Prof. Mateus Raeder
DIREITA
120
100 130
200
150
80 110
ESQUERDA
120
100 130
150
200
80 110
120
100 150
80 110 130 200
Rotação Dupla ESQUERDA
Programação II – Prof. Mateus Raeder
120
100 130
200
150
80 110
Rotação Dupla
Esquerda
120
100 150
80 110 130 200
Rotação Dupla ESQUERDA
Programação II – Prof. Mateus Raeder
k1
k3
d
b
a
k2
c
ROTAÇÃO DIREITA
k1
k2
b
c
a
k3
dk2
k3
c d
k1
a b
ROTAÇÃOESQUERDA
Rotação Dupla ESQUERDA
Programação II – Prof. Mateus Raeder
Rotação Dupla
Esquerda
k1
k3
d
b
a
k2
c
k2
k3
c d
k1
a b
private static AvlNode doDoubleLeftRotation (AvlNode k1) { k1.right = doRightRotation( k1.right ); return doLeftRotation( k1 );}
Rotação Dupla ESQUERDA
Programação II – Prof. Mateus Raeder
Resumo: Rotaçõesk2
k1
x y
z
k1
k2
y z
xRotação Direita
k2
k1
x y
z
k1
k2
y z
xRotação Esquerda
Rotação DuplaDireita k2
k3
c d
k1
a b
positivo e f. e. positivo
Rotação Dupla
Esquerda
k1
k3
d
b
a
k2
c
k2
k3
c d
k1
a b
negativo e f. d. negativo
positivo e f. e. negativo negativo e f. d. positivo
k3
k1
a
b
d
k2
c
Programação II – Prof. Mateus Raeder
Exemplos de Rotação (Esquerda e Direita)• Considere a árvore abaixo, no qual 12 está entre 9 e 15.
– Fazendo a rotação direita em 9, onde ficará 12? – Terminada a rotação a direita, tente agora a rotação a
esquerda em 15.
15
9 22
4 12
9
4 15
12 22
15
9 22
4 12
DIREITA ESQUERDA
Programação II – Prof. Mateus Raeder
Inserção em Árvores AVL220
120
80
100
300
150 260 400
110 130 200 250 270 350 500
Inserir 140
Programação II – Prof. Mateus Raeder
Inserção de nodos em árvores AVLAlguns Problemas
• 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
Programação II – Prof. Mateus Raeder
Inserção em Árvore AVLprivate 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;}
Programação II – Prof. Mateus Raeder
Inserção em Árvore AVL
public boolean insert (int x) { // se chave já existe na árvore retorna
false if (search (x)!=null) return false; // insere chave na árvore root = insert (x, root); return true; }
Programação II – Prof. Mateus Raeder
Remoção de nodos em árvores AVL
• 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
Programação II – Prof. Mateus Raeder
Remoção em Árvore AVL32
16
8
48
24 40 56
28 36 44 52 60
58 62
deletando 8
-1
-1
0
-1
-1
0
0 0
-1
0 0
0 0
0
Programação II – Prof. Mateus Raeder
Remoção em Árvore AVL32
16 48
24 40 56
28 36 44 52 60
58 62
faz balanceamento de nó pai de nó deletado
0
-1
-2
-1
-1
-1
0
00
000
0
rotação simples à esquerda
Programação II – Prof. Mateus Raeder
Remoção em Árvore AVL32
24 48
16 40 5628
36 44 52 60
58 62
volta recursivamente até a raiz, balanceando todos os nós que se encontrarem desbalanceados
00
0
0 0
0 0
00
-10
-1
-2rotação simples
à esquerda
Programação II – Prof. Mateus Raeder
Remoção em Árvore AVL
32
24
48
16
40
56
28 36 44
52 60
58 620 0
0
0 0
0
0
00
00
-1
0
Programação II – Prof. Mateus Raeder
Árvores AVL
• Applet que simula árvore AVL:http://webpages.ull.es/users/jriera/Docencia/AVL/AVL%20tree%20applet.
htm