Estrutura de Dados -...

Post on 05-Dec-2018

216 views 0 download

Transcript of Estrutura de Dados -...

Estrutura de Dados Carlos Eduardo Batista

Centro de Informática - UFPB

bidu@ci.ufpb.br

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

Estrutura de Dados Carlos Eduardo Batista

Centro de Informática - UFPB

bidu@ci.ufpb.br