Árvore AVL – Rotações - UFMT

Propaganda
Universidade Federal de Mato Grosso
Estrutura de Dados II
Curso de Ciência da Computação
Prof. Thiago P. da Silva
[email protected]
Agenda





Definições
Fator de Balanceamento
Estrutura de um Nó
Operações

Inserção

Remoção

Busca
Rotações

Rotação á esquerda

Rotação á direita

Rotação dupla á esquerda

Rotação dupla á direita
Árvore Binária - Definição


Grafo acíclico, conexo, dirigido e que cada nó não tem grau
maior que dois

Não existe mais do que um caminho entre dois nós distintos
Uma árvore binária é uma estrutura de dados caracterizada por:

Ou não tem elemento algum (árvore vazia)

Ou tem um elemento distinto, denominado raiz, com dois
ponteiros para duas estruturas diferentes, denominadas
subárvore esquerda (sae) e subárvore direita (sad)
Árvore Binária - Definição

Definições:

PROFUNDIDADE - distância de um nó até a raiz

NÍVEL – conjunto de nós com a mesma profundidade

ALTURA – maior profundidade da árvore

NÓS - são todos os itens guardados na árvore

RAIZ - é o nó do topo da árvore

FILHOS - são os nós que vem depois dos outros nós

PAIS - são os nós que vem antes dos nós filhos

FOLHAS - são os nós que não têm filhos; são os últimos nós
da árvore
Árvore AVL - Definição



Uma árvore AVL é uma árvore balanceada cuja diferença em
altura entre a subárvore esquerda (SAE) e a subárvore direita
(SAD) (em qualquer nó) deve ser, no máximo, de um nível.
Numa árvore AVL, cada chave é única e as operações de
inserção/ remoção tentam manter o equilíbrıo da árvore.
Definição: Uma árvore binária vazia é sempre balanceada por
altura. Se T não é vazia e Tesq e Tdir são sub-árvores da
esquerda e direita, então T é balanceada por altura se:

1. Tesq e Tdir são balanceadas por altura;

2. He-Hd = ±1, sendo Hd e He a altura de Tesq e Tdir,
respectivamente.
Árvore AVL - Definição

Em cada nó, existe um campo adicional que indica a situação de
equilíbrio desse nó, chamado de fator de balanceamento
(FB):

0 : equilibrada;

1 : sub-árvore esquerda tem mais um nível que a da direita;

-1 : sub-árvore direita tem mais um nível que a da esquerda
Árvore AVL – Estrutura de um Nó

Novos atributos:

FB: armazena o fator de balanceamento daquele nó dentro da árvore
AVL.

Pai: guarda a referência para o nó pai. No caso da raiz da árvore, o
pai é igual a null.
typedef struct no_AVL AVL;
struct no_AVL {
int info;
int fb; // fator de balanceamento
AVL *pai;
AVL *esq;
AVL *dir;
};
Árvore AVL – Calculando a Altura de um Nó
int altura(Arvore t)
{
int altE, altD:
AVL *q, *temp;
if (t == NULL)
return -1;
else
{
altE = altura(t->esq);
altD = altura(t->dir);
if (altE < altD)
return altD + 1;
else
return altE + 1;
}
}
Árvore AVL – Operações



Inserção

Inserção em uma árvore AVL deve ser dada pela inserção do
nodo seguida de uma verificação na propriedade do fator
de balanceamento. Caso não obedeça a essa propriedade,
deve-se fazer uma rotação conveniente.
Remoção

A remoção deve ser dada por uma rotação em torno do nó a
ser removido, a fim de torná-lo folha para que então possa ser
removido. Em alguns casos, após a remoção são necessárias
rotações para ajustar o fator de balanceamento.
Pesquisa

O número de comparações para localizar um elemento em AVL
é aproximadamente 1.44 log2 n no pior caso.
Árvore AVL – Operações


Inserção e remoção são operações que podem desbalancear a
árvore AVL.
Considere uma árvore T qualquer com raiz r e subárvores
esquerda E e direita D, e supondo que a inserção deve ser feita na
subárvore da esquerda. Podemos distriguir 3 casos:

1. Se He = Hr, então E e D ficam com alturas diferentes mas
continuam balanceadas.


2. Se He < Hd, então E e D ficam com alturas iguais e
balanceamento foi melhorado.
3. Se He > Hd, então E fica ainda maior e balanceamento foi
violado.
Árvore AVL – Operações



Exemplo:
Nós 9 ou 11 podem ser inseridos sem balanaceamento. Subárvore
com raiz 10 passa a ter uma subárvore e subárvore com raiz 8 vai
ficar melhor balanceada!
Inserção dos nós 3, 5 ou 7 requerem que a árvore seja
rebalanceada!
Árvore AVL – Inserção na árvore

Para inserir um nó X em uma árvore AVL, basta seguirmos os
seguintes passos (top-down):


(1) Inserir X na árvore AVL usando o mesmo algoritmo de inserção de
um nó em uma árvore de busca binária. Recursivamente, empilhar
cada nó que é visitado a partir do nó raiz até X, exceto o próprio X;
(2) Verificar se a pilha está vazia:
Se sim, o algoritmo termina.
 Senão, vá para o passo (3).
(3) Desempilhar um nó e verificar se a diferença de altura entre a
subárvore da esquerda e da direita desse nó é maior que 1.




Se sim, vá para o passo (2).
Senão, você precisará rotacionar os nós. Depois de
realizada a rotação, o algoritmo termina.
Árvore AVL – Inserção na árvore


Alternativamente, você pode manter um ponteiro na estrutura nó
para o seu pai. (No* pai)
Desta forma, é possível ”caminhar” de baixo para cima na árvore.
O algoritmo para na raiz, pois pai==null:


(1) Inserir X na árvore AVL. Recursivamente, empilhar cada nó que é
visitado a partir do nó até X a raiz, exceto a própria raiz;
(2) Verificar se a pilha está vazia:
Se sim, o algoritmo termina.
 Senão, vá para o passo (3).
(3) Desempilhar um nó e verificar se a diferença de altura entre a
subárvore da esquerda e da direita desse nó é maior que 1.




Se sim, vá para o passo (2).
Senão, você precisará rotacionar os nós. Depois de
Árvore AVL – Inserção na árvore

Exemplos:

10, 20, 30


30, 20, 10
Façam o desenho destas árvores!
Árvore AVL – Inserção na árvore

Exemplos:

10, 20, 30


30, 20, 10
Observações:

Quando os sinais dos fatores de balanceamento dos
antecessores forem iguais, então a rotação é simples

Se forem negativos (-), então será uma rotação à esquerda

Se forem positivo (+), então será uma rotação à direita
Árvore AVL – Rotações

Rotação à esquerda

”Empurrar o nó para baixo e para esquerda. O filho à direita do
nó o substitui, e o filho à esquerda do filho à direita vem a ser o
novo filho à direita do nó”.



Seja Y o filho à direita de X
Torne o filho à esquerda de Y o filho à direita de X.
Torne X filho à esquerda de Y
void rotacao_esquerda(AVL *p)
{
AVL *y, *temp;
y = p->dir;
temp = y->esq;
y->esq = p;
p->dir = temp;
}
Árvore AVL – Rotações

Rotação simples à esquerda:

10, 20, 30
Seja Y o filho à direita de X
Torne o filho à esquerda de Y o filho à direita de X.
●Torne X filho à esquerda de Y
●
●
10
20
20
10
30
30
Árvore AVL – Rotações

Rotação simples à esquerda:

10, 20, 30
Seja Y o filho à direita de X
Torne o filho à esquerda de Y o filho à direita de X.
●Torne X filho à esquerda de Y
●
●
FB=-2
10
20
FB=-1
20
FB=0
30
10
30
Árvore AVL – Rotações

Rotação simples à esquerda:

10, 20, 30
Seja Y o filho à direita de X
Torne o filho à esquerda de Y o filho à direita de X.
●Torne X filho à esquerda de Y
●
●
FB=-2
10
X
FB=-2
FB=-1
20
Y
10
FB=0
FEX
20
30
FEY
FEX – Filho a esquerda de X
FEY – Filho à esquerda de Y
FB=-1
Y
30
Árvore AVL – Rotações

Rotação simples à esquerda:

10, 20, 30
Seja Y o filho à direita de X
●Torne o filho à esquerda de Y o filho à direita de X.
●Torne X filho à esquerda de Y
●
FB=-2
10
X
FB=-2
FB=-1
20
Y
10
FB=0
30
FEX – Filho a esquerda de X
FEY – Filho à esquerda de Y
FEX
FB=-1
20
FEY
Y
30
Árvore AVL – Rotações

Rotação simples à esquerda:

10, 20, 30
Seja Y o filho à direita de X
●Torne o filho à esquerda de Y o filho à direita de X.
●Torne X filho à esquerda de Y
●
FB=-2
10
X
FB=-2
FB=-1
20
Y
10
FB=0
FEX
20
30
FEY
FEX – Filho a esquerda de X
FEY – Filho à esquerda de Y
FB=-1
Y
30
Árvore AVL – Rotações

Rotação simples à esquerda:

10, 20, 30
Seja Y o filho à direita de X
●Torne o filho à esquerda de Y o filho à direita de X.
●Torne X filho à esquerda de Y
●
FB=-2
10
X
FB=-1
20
Y
FB=0
20
FB=0
FB=0
30
Y
10
FEX – Filho a esquerda de X
FEY – Filho à esquerda de Y
FEX
FEY
FB=0
30
Árvore AVL – Rotações

Rotação à direita

”Empurrar o nó para baixo e para a direita. O filho à esquerda
do nó o substitui, e o filho à direita do filho à esquerda vem a
ser o novo filho à esquerda do nó.



Seja Y o filho à esquerda de X
Torne o filho à direita de Y o filho à esquerda de X.
Torne X o filho à direita de Y
void rotacao_direita(AVL *p)
{
AVL *q, *temp;
q = p->esq;
temp = q->dir;
q->dir = p;
p->esq = temp;
}
Árvore AVL – Rotações

Rotação simples à direita:

30, 20, 10
Seja Y o filho à esquerda de X
Torne o filho à direita de Y o filho à esquerda de X.
●Torne X o filho à direita de Y
●
●
30
20
10
20
10
30
Árvore AVL – Rotações

Exemplo 1:

Inserção do elemento 16 na árvore
10
15
6
3
2
7
4
17
Árvore AVL – Rotações

Exemplo 1:

Inserção do elemento 16 na árvore
FB=1
10
FB=1
FB=-1
15
6
FB=0
FB=0
3
FB=0
2
7
FB=0
4
FB=0
17
Árvore AVL – Rotações

Exemplo 1:

Inserção do elemento 16 na árvore
FB=0
10
FB=1
FB=-2
15
6
FB=0
3
FB=0
2
FB=1
FB=0
17
7
FB=0
4
FB=0
16
Árvore AVL – Rotações

Exemplo 1:

Inserção do elemento 16 na árvore
FB=0
10
FB=1
FB=-2
15
6
FB=0
FB=0
3
FB=0
2
Y
17
7
FB=0
4
FB=1
FB=0
16
Árvore AVL – Rotações

Exemplo 1:

Inserção do elemento 16 na árvore
FB=0
10
FB=1
FB=0
15
6
FB=0
FB=0
3
FB=0
2
7
FB=0
4
16
FB=0
Y
FB=0
17
Árvore AVL – Rotações

Exemplo 2:

Inserção do elemento 1 na árvore
Árvore AVL – Rotações

Exemplo 2:

Inserção do elemento 1 na árvore
10
15
6
3
2
1
7
4
17
Árvore AVL – Rotações

Exemplo 2:

Inserção do elemento 1 na árvore
10
15
6
3
2
1
7
4
17
Árvore AVL – Rotações

Exemplo 2:

Inserção do elemento 1 na árvore
10
15
3
2
1
17
6
4
7
Árvore AVL – Rotações

E para os casos em que os sinais dos fatores de balanceamento
dos antecessores forem diferentes?

Exemplo:

10, 30, 20
10
30
20
Árvore AVL – Rotações

E para os casos em que os sinais dos fatores de balanceamento
dos antecessores forem diferentes?

Exemplo:

10, 30, 20
10
30
20

Aplicamos rotações duplas
Árvore AVL – Rotações

Rotação dupla à esquerda

Rotação simples à direita

Rotação simples à esquerda
void rotacao_dupla_esquerda(AVL *p)
{
rotacao_direita(p->dir);
rotacao_esquerda(p);
}
Árvore AVL – Rotações

Rotação dupla à esquerda

Exemplo:

20
10
10
30
20
10, 30, 20
10
20
30
30
Árvore AVL – Rotações

Rotação dupla à esquerda

Exemplo:


10, 30, 20
Rotação simples à direita
Rotação simples à esquerda
20
10
10
30
20

10
20
30
30
Árvore AVL – Remoção

Como proceder:

1 - Faça a remoção como na árvore binária de busca

2 – Percorrer o caminho desde o pai do nó removido até a raiz
da árvore, verificando os fatores de balanceamento e fazendoas
rotações apropriadas

Pode ser necessária mais do que uma rotação
Árvore AVL – Rotações

Exemplo 1:

Remoção do elemento 7 na árvore
10
17
5
3
4
13
12
19
15
7
16
20
Árvore AVL – Rotações

Exemplo 1:

Remoção do elemento 7 na árvore
10
17
5
3
4
13
12
19
15
7
16
20
Árvore AVL – Rotações

Exemplo 1:

Remoção do elemento 7 na árvore
10
17
5
19
15
3
4
13
12
16
20
Árvore AVL – Rotações

Exemplo 1:

Remoção do elemento 7 na árvore
10
5
17
19
15
3
4
13
12
16
20
Árvore AVL – Rotações

Exemplo 1:

Remoção do elemento 7 na árvore
10
4
3
17
13
12
19
15
5
16
20
Árvore AVL – Rotações

Exemplo 1:

Remoção do elemento 7 na árvore
10
4
3
17
13
12
19
15
5
16
20
Árvore AVL – Rotações

Exemplo 1:

Remoção do elemento 7 na árvore
15
10
17
4
3
13
5
12
16
19
20
Download