A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Capítulo IV – Árvores Gerais

Apresentações semelhantes


Apresentação em tema: "Capítulo IV – Árvores Gerais"— Transcrição da apresentação:

1 Capítulo IV – Árvores Gerais
4.1 – Definições e terminologia básica 4.2 – Formas de representação de árvores 4.3 – Ordenação dos nós de uma árvore 4.4 – Operadores para o TAD árvore 4.5 – Estruturas contíguas para árvores 4.6 – Estruturas encadeadas para árvores

2 4.5 – Estruturas Contíguas para Árvores
Nesta disciplina, são apresentadas 5 estruturas de dados para árvores divididas em 2 grupos: Estruturas contíguas Estruturas encadeadas Estrutura contígua comum Estrutura contígua incrementada Estrutura encadeada direta Estrutura com listas de filhos Estrutura com encadeamento de pais e irmãos

3 4.5.1 – Estrutura contígua comum
Os nós são armazenados num vetor de células, numa ordem convencionada Exemplo: estrutura contígua da árvore abaixo: A 3 1 B 2 E C 4 F 5 G 6 D 7 H 8 I 9 J 10 K 11 # info grau noh Espaco ncel Celula arvore A nó é o índice da célula no vetor de células Por convenção, a ordem será a pré-ordem

4 Declarações: A 3 1 B 2 E C 4 F 5 G 6 D 7 H 8 I 9 J 10 K 11 # info grau
const int max = 100; const int nulo = 0; const int absurdo = -9999; typedef int noh; typedef char informacao; struct celula {informacao info; int grau;}; struct arvore {celula Espaco [101]; int ncel;}; A 3 1 B 2 E C 4 F 5 G 6 D 7 H 8 I 9 J 10 K 11 # info grau noh Espaco ncel Celula arvore A

5 Operadores de árvores na estrutura contígua comum:
noh FilhoEsquerdo (noh n, arvore A) { if (n <= 0 || n > A.ncel) return absurdo; if (A.Espaco[n].grau == 0) return nulo; else return n + 1; } informacao Elemento (noh n, arvore A) { return A.Espaco[n].info; A 3 1 B 2 E C 4 F 5 G 6 D 7 H 8 I 9 J 10 K 11 # info grau noh Espaco ncel Celula arvore A

6 A 3 1 B 2 E C 4 F 5 G 6 D 7 H 8 I 9 J 10 K 11 # info grau noh Espaco
noh Raiz (arvore A) { if (A.ncel == 0) return nulo; return 1; } logic ArvVazia (arvore A) { if (A.ncel == 0) return TRUE; else return FALSE; void Esvaziar (arvore *A) { A->ncel = 0; } A 3 1 B 2 E C 4 F 5 G 6 D 7 H 8 I 9 J 10 K 11 # info grau noh Espaco ncel Celula arvore A

7 Operador Pai (n, A): não é imediato
O pai de n é algum nó n1 à sua esquerda A H G F D C E B K J I Entre n e seu pai estão todos os irmãos de n mais à esquerda e seus descendentes próprios Por exemplo, deseja-se achar o pai do nó 10 (conteúdo D) n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # info grau noh Espaco ncel

8 Percorrendo o vetor com n1, será contado o número de nós-soltos:
Nó-solto: é um nó tal que, no percurso de n1 para a esquerda, seu pai ainda não foi encontrado n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

9 Inicialmente, obviamente, n (conteúdo D) é um nó-solto
Relação de nos soltos 1 nossoltos n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

10 Grau (n1 ou H) = 0, logo nenhum nó-solto deixou de ser solto
O próprio nó n1 é um nó-solto Relação de nos soltos nossoltos 2 1 D H D n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

11 Grau (n1 ou K) = 0, logo nenhum nó-solto deixou de ser solto
O próprio nó n1 é um nó-solto Relação de nos soltos nossoltos 3 2 H D K H D n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

12 Grau (n1 ou J) = 1, logo 1 nó-solto deixou de ser solto
O próprio nó n1 é um nó-solto Relação de nos soltos nossoltos 3 3 K H D J H D n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

13 Grau (n1 ou I) = 0, logo nenhum nó-solto deixou de ser solto
O próprio nó n1 é um nó-solto Relação de nos soltos nossoltos 4 3 J H D I J H D n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

14 Grau (n1 ou G) = 2, logo 2 nós-soltos deixaram de ser soltos
O próprio nó n1 é um nó-solto Relação de nos soltos nossoltos 3 4 I J H D G H D n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

15 Grau (n1 ou C) = 2, logo 2 nós-soltos deixaram de ser soltos
O próprio nó n1 é um nó-solto Relação de nos soltos nossoltos 2 3 G H D C D n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

16 Grau (n1 ou F) = 0, logo nenhum nó-solto deixou de ser solto
O próprio nó n1 é um nó-solto Relação de nos soltos nossoltos 3 2 C D F C D n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

17 Grau (n1 ou B) = 1, logo 1 nó-solto deixou de ser solto
O próprio nó n1 é um nó-solto Relação de nos soltos nossoltos 3 3 F C D B C D n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

18 Grau (n1 ou A) = 4, logo 4 nós-soltos deixaram de ser soltos
Mas o número de nós-soltos era 3, logo: nó 1 (conteúdo A) é pai do nó 10 (conteúdo D) D não é caçula (seria se Grau (A) fosse 3) B C D Relação de nos soltos 3 nossoltos n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

19 O mesmo esquema pode ser usado para responder se um nó é ou não caçula
Apesar da estrutura definir completamente a árvore, o algoritmo não é trivial B C D Relação de nos soltos 3 nossoltos n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

20 noh Pai (noh n, arvore A) {
noh n1; int nossoltos; if (n <= 0 || n > A.ncel) return absurdo; if (n == 1) return nulo; nossoltos = 1; n1 = n - 1; while (1) if (A.Espaco[n1].grau >= nossoltos) return n1; else { nossoltos += 1 - A.Espaco[n1].grau; n1--; } n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

21 logic Cacula (noh n, arvore A) {
noh n1; int nossoltos; if (n <= 0 || n > A.ncel) return absurdo; if (n == 1) return TRUE; nossoltos = 1; n1 = n - 1; while (1) if (A.Espaco[n1].grau > nossoltos) return FALSE; else if (A.Espaco[n1].grau == nossoltos) return TRUE; else { nossoltos += 1 - A.Espaco[n1].grau; n1--; } n1 n A 4 1 B 2 F 3 C G 5 I 6 J 7 K 8 H 9 D 10 E 11 # ncel

22 Operador IrmaoDireito (n, A): também não é imediato
Se n não for caçula, seu irmão direito será algum nó n1 à sua direita A H G F D C E B K J I Entre n e seu irmão direito estão todos os descendentes próprios de n Por exemplo, deseja-se achar o irmão direito do nó 4 (conteúdo C) A 3 1 B 2 F C 4 G 5 H 6 I 7 J 8 K 9 D 10 E 11 # info grau noh Espaco ncel n n1

23 Percorrendo o vetor com n1, será contado o número de descendentes próprios de n
Para n1 ser o irmão direito de n, a diferença (n1-n) deve ser maior que o número de descendentes próprios já detectados A 3 1 B 2 F C 4 G 5 H 6 I 7 J 8 K 9 D 10 E 11 # info grau noh Espaco ncel n n1

24 Inicializa-se o número de descendentes próprios de n com Grau (n):
1 n1-n 2 descendentes A 3 1 B 2 F C 4 G 5 H 6 I 7 J 8 K 9 D 10 E 11 # info grau noh Espaco ncel n n1

25 Ao número de descendentes de n soma-se Grau (n1 ou G)
n1-n descendentes 2 2 1 2 A 3 1 B 2 F C 4 G 5 H 6 I 7 J 8 K 9 D 10 E 11 # info grau noh Espaco ncel n n1 n1

26 Ao número de descendentes de n soma-se Grau (n1 ou H)
n1-n descendentes 2 4 2 3 A 3 1 B 2 F C 4 G 5 H 6 I 7 J 8 K 9 D 10 E 11 # info grau noh Espaco ncel n n1 n1

27 Ao número de descendentes de n soma-se Grau (n1 ou I)
n1-n descendentes 4 4 3 4 A 3 1 B 2 F C 4 G 5 H 6 I 7 J 8 K 9 D 10 E 11 # info grau noh Espaco ncel n n1 n1

28 Ao número de descendentes de n soma-se Grau (n1 ou J)
n1-n descendentes 5 4 4 5 A 3 1 B 2 F C 4 G 5 H 6 I 7 J 8 K 9 D 10 E 11 # info grau noh Espaco ncel n n1 n1

29 Ao número de descendentes de n soma-se Grau (n1 ou K)
Conclusão: nó 10 (conteúdo D) é o irmão direito do nó 4 (conteúdo C) n1-n descendentes 5 5 5 6 A 3 1 B 2 F C 4 G 5 H 6 I 7 J 8 K 9 D 10 E 11 # info grau noh Espaco ncel n n1 n1

30 A 3 1 B 2 F C 4 G 5 H 6 I 7 J 8 K 9 D 10 E 11 # info grau noh Espaco
noh IrmaoDireito (noh n, arvore A) { noh n1; int descendentes; if (n <= 0 || n > A.ncel) return absurdo; if (Cacula (n, A) == TRUE) return nulo; descendentes = A.Espaco[n].grau; n1 = n + 1; while (1) if (n1 - n > descendentes) return n1; else { descendentes += A.Espaco[n1].grau; n1++; } A 3 1 B 2 F C 4 G 5 H 6 I 7 J 8 K 9 D 10 E 11 # info grau noh Espaco ncel n n1

31 Observações: Na maioria dos casos essa estrutura é ineficiente, porém:
Gasta relativamente pouca memória Serve para armazenamento permanente Para sua manipulação, converte-se para uma estrutura mais eficiente Para armazenamento, converte-se de volta para a estrutura contígua

32 4.5.2 – Estrutura contígua incrementada
A estrutura contígua pode ser incrementada, incluindo-se nas células, informações de caráter operacional Exemplo: estrutura contígua com informações sobre o pai de cada nó A 3 B 1 E 2 C F 4 G D H 7 I 8 J K # info grau pai Espaco 11 ncel arvore A 5 6 9 10 noh Celula

33 Declarações: A 3 B 1 E 2 C F 4 G D H 7 I 8 J K # info grau pai Espaco
const int max = 100; const int nulo = 0; const int absurdo = -9999; typedef int noh; typedef char informacao; struct celula {informacao info; int grau, pai;}; struct arvore {celula Espaco [101]; int ncel;}; A 3 B 1 E 2 C F 4 G D H 7 I 8 J K # info grau pai Espaco 11 ncel arvore A 5 6 9 10 noh Celula

34 O operador Pai (n, A) fica elementar:
noh Pai (noh n, arvore A) { if (n <= 0 || n > A.ncel) return absurdo; else return A.Espaco[n].pai; } Para o operador IrmaoDireito (n, A), basta encontrar o primeiro nó à direita de n, com o mesmo pai de n A 3 B 1 E 2 C F 4 G D H 7 I 8 J K # info grau pai Espaco 11 ncel arvore A 5 6 9 10 noh

35 Mais eficiente e de programação mais simples
noh IrmaoDireito (noh n, arvore A) { noh n1; if (n < 1 || n >= A.ncel) return absurdo; else if (n == 1) return nulo; else { n1 = n+1; while (n1 <= A.ncel) if (A.Espaco[n1].pai == A.Espaco[n].pai) return n1; else n1++; } return nulo; Mais eficiente e de programação mais simples A 3 B 1 E 2 C F 4 G D H 7 I 8 J K # info grau pai Espaco 11 ncel arvore A 5 6 9 10 noh

36 Caminhar de um nó até a raiz é simples
Difícil continua sendo o trabalho de inserir e deletar sub-árvores A 3 B 1 E 2 C F 4 G D H 7 I 8 J K # info grau pai Espaco 11 ncel arvore A 5 6 9 10 noh


Carregar ppt "Capítulo IV – Árvores Gerais"

Apresentações semelhantes


Anúncios Google