estrutura de dados -...
TRANSCRIPT
Estruturas de Dados
Árvores (parte 4)
2
Árvores
Organização dos dados: ◦ Linear:
Listas, pilhas, filas.
Relação sequencial.
◦ Não-linear:
Outros tipos de relação entre dados;
Hierarquia;
Árvores
Grafos.
3
Árvores binárias de pesquisa 4
Árvores binárias de pesquisa
Solução para implementação da busca binária encadeada.
Busca binária sequencial: ◦ Cada comparação na busca binária reduz o número de possíveis candidatos por uma fator de 2. Sendo assim, o número máximo de comparações da chave é aproximadamente log2N.
Árvore binária de pesquisa: ◦ Quando a árvore tem altura mínima possui o mesmo comportamento.
5
Árvores binárias de pesquisa
Implementação: ◦ Mudança nos métodos:
Busca (pesquisa);
Inserção
Remoção
Exibição só in-ordem
6
Árvores binárias de pesquisa 7
t_no * busca(t_arvore tree, t_elemento dado)
{
t_no* achou;
if (tree == NULL)
return NULL;
if (compara(tree->dado, dado)==0)
return tree;
achou = busca(tree->esq, dado);
if (achou == NULL)
achou = busca(tree->dir, dado);
return achou;
}
Árvores binárias de pesquisa 8
t_no * busca(t_arvore tree, t_elemento dado)
{
if (tree == NULL)
return NULL;
if (compara(tree->dado, dado)==0)
return tree;
if (compara(tree->dado, dado)>0)
return busca(tree->esq, dado);
else
return busca(tree->dir, dado);
}
Árvores binárias de pesquisa 9
t_no * buscaSetPai(t_arvore tree, t_elemento dado, t_no ** pai)
{
if (tree == NULL) {
*pai = NULL;
return NULL;
}
if (compara(tree->dado, dado)==0)
return tree;
if (compara(tree->dado, dado)>0) {
*pai = tree;
return buscaSetPai(tree->esq, dado, pai);
}
else {
*pai = tree;
return buscaSetPai(tree->dir, dado, pai);
}
}
Árvores binárias de pesquisa 10
int inserir (t_arvore *tree, t_elemento item)
{
int ok;
// se a raiz for nula, entao insere na raiz
if (*tree == NULL) {
*tree = criar();
if (*tree == NULL)
return 0;
(*tree)->dado = item;
return 1;
}
if (compara((*tree)->dado, item)<0)
ok = inserir (&((*tree)->dir), item);
else
if (compara((*tree)->dado, item)>0)
ok = inserir (&((*tree)->esq), item);
else
ok = 0;
return ok;
}
Árvores binárias de pesquisa
Remoção ◦ Nó a ser removido não possui filhos:
Remove-se o nó e a ligação do pai com o filho é anulada.
◦ Nó a ser removido possui apenas 1 filho:
Remove-se o nó e o pai passa a apontar para o ex-neto, que agora vira filho.
◦ Nó a ser removido possui dois filhos:
Obtém-se o sucessor do nó. O sucessor vai para o lugar do no a ser excluído. O pai do sucessor, aponta agora para o ex-neto. O sucessor->dir passa a apontar para onde o no->dir apontava.
11
Árvores binárias de pesquisa 12
Árvores binárias de pesquisa
Sucessor: ◦ Menor nó do conjunto de nós maiores que o nó atual.
Antecessor: ◦ Maior nó do conjunto de nós menores que o nó atual.
13
Árvores binárias de pesquisa 14
int remover (t_arvore *tree, t_elemento item) {
t_no *no, // no aponta para o no a ser removido
*pai, // pai aponta para o pai do no
*sub, // sub aponta que ira substituir o no no
*paiSuce, // pai do no sucessor
*suce; // sucessor do no no
no = *tree; pai=NULL;
no = buscaSetPai(*tree, item, &pai); // procura o no a ser removido, e seta o seu pai.
if (no==NULL)
return 0; // a chave nao existe na arvore, nao conseguiu remover
if (no->esq == NULL) // ver os dois primeiros casos, o no tem um filho no maximo
sub = no->dir;
else {
if (no->dir == NULL)
sub = no->esq;
else { // caso em que o no tem dois filhos
}}
// insere sub na posicao ocupada anteriormente por no
if (pai == NULL) // no eh a raiz, nao tem pai
*tree = sub;
else // verifica se o no eh o filho da esquerda ou da direita
if (no == pai->esq)
pai->esq = sub;
else
pai->dir = sub;
free(no); // libera o no
return 1; // verdadeiro, conseguiu remover
}
Árvores binárias de pesquisa 15
else { // caso em que o no tem dois filhos
paiSuce=no;
sub = no->dir;
suce = sub->esq; // suce eh sempre o filho esq de sub
while (suce != NULL) {
paiSuce = sub;
sub = suce;
suce = sub->esq;
}
// neste ponto, sub eh o sucessor em ordem de no
if (paiSuce != no) {
// no nao e o pai de sub, e sub == paiSuce->esq
paiSuce->esq = sub->dir;
// remove o no sub de sua atual posicao e o
// substitui pelo filho direito de sub
// sub ocupa o lugar de no
sub->dir = no->dir;
}
// define o filho esquerdo de sub de modo que sub
// ocupe o lugar de no
sub->esq = no->esq;
}
Árvore binária estrita
Todo nó não folha possui filhos a esquerda e a direita = Árvore Binária Estrita
Uma árvore binária estrita com n folhas sempre contém 2n-1 nós
16
Árvores binárias
Árvore binária cheia de nível d: árvore binária estrita com todas as folhas no nível d
Árvore binária completa de nível d: uma árvore binária estrita com todas as folhas no nível d ou no nível d-1
17
Árvores binárias 18
D E
B
H I
F G
C
A
H I
D
J K
E
B
L M
F
N O
G
C
A
Completa Cheia
Árvores binárias
O total de nós n em uma árvore binária cheia de altura d é a soma do número de nós a cada nível
n = 20 + 21 + 22 + ..... + 2d = Ʃ 2j
n = 2d+1 -1 d = log (n+1) –1
número de folhas de uma árvore cheia com n nós
2d = 2log(n+1)-1 = 2log(n+1) = n+1 2 2
19
Árvores binárias 20
H I
D
J K
E
B
L M
F
N O
G
C
A
Árvore Binária Cheia de altura 3 23+1-1 = 15 nós
Árvores binárias
Seja T uma árvore binária completa com n nós, então sua altura h = log2n
Seja T’ a árvore obtida pela remoção dos k nós do último nível
T’ é cheia já que T só tinha folhas no último e no penúltimo nível (definição de completa)
nós de T’
n’ = n - k = 2d +1 -1 , onde d é a altura de T’
21
Árvores AVL
Os algoritmos convencionais podem gerar árvores degeneradas ou ótimas ◦ Árvores de crescimento irrestrito
Árvores AVL (Adelson-Velskki & Landis) ◦ Árvores de busca binária auto-balanceada ◦ Nesse tipo de árvore, as alturas das duas sub-
árvores a partir de cada nó difere no máximo em uma unidade.
◦ Mesmo depois de inclusões e exclusões o custo se mantem O (log n) onde n é o numero de nós
◦ Inserções e eliminações podem requerer o rebalanceamento da árvore, exigindo uma ou mais rotações.
22
Árvores AVL 23
Árvores AVL
Dizemos que uma árvore está balanceada em altura (ou profundidade) quando, para cada nó, a diferença entre as alturas de suas sub-árvores é igual a -1, 0 ou 1.
24
Árvores AVL 25
Árvores AVL
Fator de equilíbrio de um nó
Fe(A) = hEsq – hDir
Fe(A) = 2 – 3 = -1
Fe(C) = 2 – 1 = 1
AVL Fe(N) {-1, 0, +1}; N
26
Árvores AVL
Fe(A) = 2 – 3 = -1 Fe(B) = 1 – 1 = 0 Fe(C) = 2 – 1 = 1 Fe(D) = 0 – 0 = 0 Fe(E) = 0 – 0 = 0 Fe(F) = 1 – 1 = 0 Fe(G) = 0 – 0 = 0 Fe(H) = 0 – 0 = 0 Fe(I) = 0 – 0 = 0
27
Árvores AVL 28
Com base na tabela acima, se tivéssemos 1.048.575 elementos, poderíamos armazená-los em uma árvore binária perfeitamente balanceada com 20 níveis. Em outras palavras, poderíamos localizar um elemento qualquer dentro dessa árvore com apenas 20 comparações.
Árvores AVL
O que pode acontecer quando um novo nó é inserido numa árvore balanceada ?
Dada uma raiz r com subárvores L (left) e R (right), e supondo que a inserção deve ser feita na sub-árvore da esquerda. Podemos distriguir 3 casos: ◦ Se hL = hR, então L e R ficam com alturas
diferentes mas continuam balanceadas. ◦ Se hL < hR, então L e R ficam com alturas iguais e
balanceamento foi melhorado. ◦ Se hL > hR, então L fica ainda maior e
balanceamento foi violado.
29
Árvores AVL
Inserindo em H ou I, dois casos ◦ Em H: Fe(F) = 1, Fe(C) = 2, F(A) = -2
◦ Em I: Fe(F) = -1, Fe(C) = 2, F(A) = - 2
Inserir e depois rotacionar visto ser necessário alguns ajustes, tal que: ◦ Continue ABB
◦ Continue balanceada
30
Árvores AVL
Rotação simples ◦ Uma rotação simples ocorre quando um nó está desbalanceado e seu filho estiver no mesmo sentido da inclinação, formando uma linha reta.
Rotação dupla ◦ Ocorre quando um nó estiver desbalanceado e seu filho estiver inclinado no sentido inverso ao pai, formando um “joelho”.
31
Árvores AVL
Rebalanceamento mapeado em dois casos ◦ Raíz (2|-2) e filho (1|-1) com o mesmo sinal
Rotação simples do nó com |Fe| = 2 na direção correta
◦ Raíz (2|-2) com um sinal e filho(-1|1) com outro
Rotação do nó com |Fe| = 1 na direção correta
Rotação do nó que tinha |Fe| = 2 na direção oposta
32
Árvores AVL
Rotação à direita ◦ Numa árvore binária basta empurrar o nó N para baixo e para a direita. O filho à esquerda de N o substitui, e o filho à direita do filho à esquerda vem a ser o novo filho à esquerda de N. Segue pseudocódigo:
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
33
Árvores AVL
Rotação à esquerda ◦ Em uma árvore binária, basta empurrar o nó N para baixo e para a esquerda. O filho à direita de N o substitui, e o filho à esquerda do filho à direita vem a ser o novo filho à direita de N. Segue pseudocódigo:
Seja Y o filho à direita de X
Torne o filho à esquerda de Y o filho à direita de X.
Torne X filho à esquerda de Y
34
35
Exemplos de Rotação Simples
Suponha que nós queiramos inserir o nó 3 na árvore inicial abaixo
3
0 8
4 10
2 6
0
0 0
-1 8
4 10
2 6
3
-1 0
+1 0
-2
0
Rotação a direita (nó 8)
0
0
0 0
4
2 8
1063
+1 0
36
Exemplo de Rotação Dupla
Suponha que queiramos inserir o nó 5 na árvore abaixo
0 8
4 10
2 6
0
0 0
-1
0
8
4 10
2 6
5
0
0
-1
+1
-2
(a) 8
6 10
4
52
0
0
0
0 -2
-2
37
Exemplo de Rotação Dupla
8
6 10
4
52
0
0
0
0 -2
-2
(b) 6
4 8
2 105
0
0
0
0 0
+1
AVL
|HR – HL| < 2
Exemplos: h = 2
h = 1 h = 0
h = 0 h = 0
É AVL
AVL
|HR – HL| < 2
Exemplos: h = 2
h = 1
h = 0 h = 0
NÃO É AVL
AVL
Fator de balanceamento b = HR – HL
Exemplo: b = 0
b = 0 b = +1
b = 0 b = 0 b = 0
AVL
Inserção ◦ Semelhante à inserção em árvore binária de busca
◦ Pode desbalancear a árvore
AVL
Exemplo ◦ Inserção do valor 5
b = 0
b = -1 b = +1
b = 0 b = 0
b = 0
b = -2
b = -1
b = 0
b = +1
b = 0
AVL
Caso a
AVL
Caso b
AVL
Caso c
AVL
Caso d
AVL
Remanejamento das árvores ◦ Rotação simples à direita
◦ Rotação dupla à direita
◦ Rotação simples à esquerda
◦ Rotação dupla à esquerda
AVL
Rotação simples à direita
AVL
Rotação simples à direita ◦ ne é colocado na raiz
◦ EE permanece a sub-árvore esquerda de ne
◦ n torna-se a raiz da sub-árvore direita de ne
◦ ED torna-se sub-árvore esquerda de n
◦ D permanece a sub-árvore direita de n
AVL
Rotação dupla à direita
AVL
O caso c é similar ao caso a
AVL
O caso d é similar ao caso b
AVL
A remoção é similar à remoção em árvore binária de busca ◦ Primeiro, busca-se o nó que contém o valor a ser removido.
◦ Se o nó for folha, remove-o
◦ Se o nó possuir um filho, esse filho substitui o nó
◦ Senão, busca-se a menor (maior) folha da sub-árvore direita (esquerda) do nó, substitui o nó por essa folha
AVL
A remoção pode desbalancear a árvore ◦ Exemplo 1: remover 25
AVL
Exemplo 1
AVL
Exemplo 1
AVL
Exemplo 2: ◦ Retirar 70
AVL
Exemplo 2:
AVL
Exemplo 2:
AVL
Exemplo 3: ◦ Retirar 50
AVL
Exemplo 3:
AVL
Exemplo 3:
AVL
Exemplo 3:
AVL
Exemplo 3:
Exercícios 65
Balancear
AVL-Inserir (T, x) Entrada: Árvore AVL e um elto x para inserção em T. Saída: Árvore AVL (T + x) Início 1. Use o algoritmo de inserção para árvore de busca binária. 2. Se (T + x) é AVL então devolva (T + x) 3. senão T' = AVL-Balance (T + x). 4. Devolva T' . Fim
AVL-Remoção(T,x) Entrada: árvore AVL e o nó x a ser removido em T. Saída: árvore AVL (T – x). Início 1. Execute a remoção como na aŕvore binária de busca. 2. Verifique se a árvore ficou desregulada (use o fator de balanceamento como na inserção). 3. Execute uma ou mais rotações (simples ou dupla). 4. Devolva (T – x). Fim
Árvore rubro negra
Uma árvore rubro-negra é uma árvore de busca binária onde cada nó tem um atributo de cor, vermelho ou preto. Além dos requisitos ordinários impostos pelas árvores de busca binárias, as árvores rubro-negras tem os seguintes requisitos adicionais: ◦ Um nó é vermelho ou preto. ◦ A raiz é preta. (Esta regra é usada em algumas definições.
Como a raiz pode sempre ser alterada de vermelho para preto, mas não sendo válido o oposto, esta regra tem pouco efeito na análise.)
◦ Todas as folhas(null) são pretas. ◦ Ambos os filhos de todos os nós vermelhos são pretos. ◦ Todo caminho de um dado nó para qualquer de seus nós
folhas descendentes contem o mesmo número de nós pretos.
68
Árvore rubro negra 69
Árvore B
Árvore B ou B-Tree é um tipo de árvores muito utilizado em banco de dados e em sistemas de arquivos.
Para inserir ou remover variáveis de um nó, o nó não poderá ultrapassar sua ordem e nem ser menor que sua ordem dividida por dois.
Árvores B não precisam ser rebalanceadas como são freqüentemente as árvores de busca binária com Árvore AVL.
Árvores B têm vantagens substanciais em relação a outros tipos de implementações quanto ao tempo de acesso e pesquisa aos nós.
70
Árvore B
Uma árvore B de ordem "m" (máximo de filhos para cada nó) é uma árvore que atende as seguintes propriedades:
◦ Cada nó tem no máximo "m" filhos
◦ Cada nó (exceto a raíz e as folhas) tem pelo menos "m/2" filhos
◦ A raiz tem pelo menos dois filhos se a mesma não for uma folha
◦ Todas as folhas aparecem no mesmo nível e não carregam informação
◦ Um nó não-folha com "k" filhos deve ter k-1 chaves
71
Árvore B 72
2ª. Prova – 20/03
Reposição – 25/03
Final – 27/03
2º. Trabalho – Deadline 22/03 23h59 GMT-3
73
Referências
Notas de Aula do Prof. Bruno B. Boniati
Notas de Aula do Prof. João Luís Garcia Rosa
Notas de Aula do Prof. Derzu Omaia
74