prof. hilton cardoso marins junior hiltonmarins@gmail.com Árvores binÁrias

Post on 22-Apr-2015

106 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Prof. Hilton Cardoso Marins Juniorhiltonmarins@gmail.com

ÁRVORES BINÁRIAS

Árvores Binárias

São estruturas do tipo árvore, onde o grau de cada nó é menor ou igual a 2.

Quando o grau do nó for igual a 2 temos a subárvore a direita (sad) e a subárvore a esquerda (sae), quando o grau do nó for igual a 1 temos uma subárvore direita ou uma subárvore esquerda e se o grau do nó for igual a 0 não temos subárvores.

Aplicação:

Representação de expressões aritméticas de tal forma que a hierarquia dos operadores fique clara.

Em operações de ordenação.

Exemplo de Árvore Binária

A expressão (a * b) + (c / (d + e)) poderia ser representada da seguinte forma:

+

:*

ba +c

ed

Definição

Uma árvore binária T é um conjunto finito de elementos denominados nós ou vértices, tal que:

T = Ø e a árvore é dita vazia, ou

Existe um nó especial r, chamado raiz de T, e os restantes podem ser divididos em dois subconjuntos disjuntos, Tr

L e Tr

R a subárvore esquerda e a direita de r,respectivamente, as quais são também

árvores binárias.

Tipos de Árvores Binárias Árvore estritamente binária:

Cada nó possui 0 ou 2 filhos.

Árvore binária completa:Se v é um nó tal que alguma subárvore de v é

vazia, então v se localiza ou no último (maior) ou no penúltimo nível da árvore.

Árvore binária cheia:Se v é um nó tal que alguma subárvore de v é

vazia, então v se localiza no último (maior) nível da árvore. v é um nó folha.

Árvore Binária

Em uma árvore binária cheia o número de nós do nível i é igual a 2i.

Consequentemente, em qualquer árvore binária existe no máximo 2i nós no nível i.

20 = 1

21 = 2

22 = 4

23 = 8

Representação de uma Árvore Binária por Contiguidade

O nó será uma estrutura com um campo de informação e duas referências, uma para a sae (subárvore esquerda) e outra para a sad (subárvore direita).

A Raiz localiza-se na primeira célula (índice 0)

-1 indica filho nuloÍndice Informação sae sad

0 13 4 2

1 31 6 -1

2 25 7 1

3 12 -1 -1

4 10 5 3

5 2 -1 -1

6 29 -1 -1

7 20 -1 -1

13

10 25

3112 202

29

Representação de uma Árvore Binária por Encadeamento

O nó é formado por uma estrutura composta de:

Campo de informaçãoPonteiro para sae.

Ponteiro para sad.sae info sad

A

sae info sad

B null

sae info sad

C

sae info sad

null D

sae info sad

E

sae info sad

null F null

sae info sad

null H null

sae info sad

null I null

sae info sad

null G null

Operações com Árvore Binária por Encadeamento

Para exemplificarmos operações com uma árvore binária por encadeamento utilizaremos a definição abaixo:

struct TipoArvore { int info; struct TipoArvore* sae; struct TipoArvore* sad;};

typedef struct TipoArvore Arvore;

Trata-se de uma árvore binária encadeada de números inteiros, todos os exemplos podem ser adaptados para qualquer outro tipo de dado básico ou estruturado.

Operações com Árvore Binária por Encadeamento

//cria uma árvore vaziaArvore* inicializa();

//verifica se a arvore está vaziaint estaVazia(Arvore* a);

//cria um nó, dado a informação e as duas subárvoresArvore* criaNo(int n, Arvore* sae, Arvore* sad);

//libera a estrutura da árvoreArvore* libera(Arvore* a);

//Determinar se uma informação se encontra ou não na árvoreint busca(Arvore* a, int n);

//imprime a informação de todos os nós da árvorevoid imprime(Arvore* a);

//Determinar a altura de uma árvoreint getAltura(Arvore* a);

//Contar quantas são as folhas de uma árvoreint getfolhas(Arvore* a);

O programa principalint main(){ Arvore *D = criaNo(4, inicializa(), inicializa()); Arvore *E = criaNo(5, inicializa(), inicializa()); Arvore *F = criaNo(6, inicializa(), inicializa()); Arvore *G = criaNo(7, inicializa(), inicializa()); Arvore *B = criaNo(2, D, E); Arvore *C = criaNo(3, F, G); Arvore *A = criaNo(1, B, C);

imprime(A);

printf("\nAltura da arvore = %d", getAltura(A));

if (!busca(A, 113)){ printf("\nInformacao INEXISTENTE!"); }else{ printf("\nInformacao ENCONTRADA COM SUCESSO!"); }

printf("\nQuantidade de folhas = %d", getFolhas(A));

A = libera(A); imprime(A); return 0;}

1, 2, 4, 5, 3, 6 e 7

2

4

Não haverá saída!

Analisando a chamada da função main:

Arvore *D = criaNo(4, inicializa(), inicializa());

/* cria uma árvore vazia. */Arvore* inicializa(){ return NULL;}

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

nullnull

Analisando a chamada da função main:

Arvore *D = criaNo(4, inicializa(), inicializa());

/* cria uma árvore vazia. */Arvore* inicializa(){ return NULL;}

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

nullnull

p

Analisando a chamada da função main:

Arvore *D = criaNo(4, inicializa(), inicializa());

/* cria uma árvore vazia. */Arvore* inicializa(){ return NULL;}

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

nullnull

sae info sad

null 4 null

p

Analisando a chamada da função main:

Arvore *D = criaNo(4, inicializa(), inicializa());

/* cria uma árvore vazia. */Arvore* inicializa(){ return NULL;}

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

nullnull

sae info sad

null 4 null

D

Analisando a chamada da função main:

Arvore *E = criaNo(5, inicializa(), inicializa());

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 4 null

D

sae info sad

null 5 null

E

Analisando a chamada da função main:

Arvore *F = criaNo(6, inicializa(), inicializa());

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 4 null

D

sae info sad

null 5 null

E

sae info sad

null 6 null

F

Analisando a chamada da função main:

Arvore *G = criaNo(7, inicializa(), inicializa());

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 4 null

D

sae info sad

null 5 null

E

sae info sad

null 6 null

F

sae info sad

null 7 null

G

Analisando a chamada da função main:

Arvore *B = criaNo(2, D, E);

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 4 null

D

sae info sad

null 5 null

E

sae info sad

null 6 null

F

sae info sad

null 7 null

G

Analisando a chamada da função main:

Arvore *B = criaNo(2, D, E);

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 4 null

D

sae info sad

null 5 null

E

sae info sad

null 6 null

F

sae info sad

null 7 null

G

sae info sad

null null

p

Analisando a chamada da função main:

Arvore *B = criaNo(2, D, E);

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 4 null

sae info sad

null 5 null

sae info sad

null 6 null

F

sae info sad

null 7 null

Gsae info sad

2

p

D E

Analisando a chamada da função main:

Arvore *B = criaNo(2, D, E);

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 6 null

F

sae info sad

null 7 null

G

sae info sad

null 4 null

sae info sad

null 5 null

sae info sad

2

B

D E

Analisando a chamada da função main:

Arvore *C = criaNo(3, F, G);

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 6 null

F

sae info sad

null 7 null

G

sae info sad

null 4 null

sae info sad

null 5 null

sae info sad

2

B

D E

Analisando a chamada da função main:

Arvore *C = criaNo(3, F, G);

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 6 null

F

sae info sad

null 7 null

G

sae info sad

null 4 null

sae info sad

null 5 null

sae info sad

2

B

D E

sae info sad

null null

p

Analisando a chamada da função main:

Arvore *C = criaNo(3, F, G);

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 6 null

F

sae info sad

null 7 null

G

sae info sad

null 4 null

sae info sad

null 5 null

sae info sad

2

B

D Esae info sad

3

p

Analisando a chamada da função main:

Arvore *C = criaNo(3, F, G);

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 6 null

F

sae info sad

null 7 null

G

sae info sad

null 4 null

sae info sad

null 5 null

sae info sad

2

B

D Esae info sad

3

C

Analisando a chamada da função main:

Arvore *A = criaNo(1, B, C);

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 6 null

F

sae info sad

null 7 null

G

sae info sad

null 4 null

sae info sad

null 5 null

sae info sad

2

B

D Esae info sad

3

C

Analisando a chamada da função main:

Arvore *A = criaNo(1, B, C);

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 6 null

F

sae info sad

null 7 null

G

sae info sad

null 4 null

sae info sad

null 5 null

sae info sad

2

B

D Esae info sad

3

C

sae info sad

null null

p

Analisando a chamada da função main:

Arvore *A = criaNo(1, B, C);

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 6 null

F

sae info sad

null 7 null

G

sae info sad

null 4 null

sae info sad

null 5 null

sae info sad

2

B

D Esae info sad

3

C

sae info sad

1

p

Analisando a chamada da função main:

Arvore *A = criaNo(1, B, C);

/* cria um nó com a informação, a sae e a sad. */Arvore* criaNo(int n, Arvore* sae, Arvore* sad){ Arvore* p = (Arvore*) malloc(sizeof(Arvore)); p->info = n; p->sae = sae; p->sad = sad; return p;}

sae info sad

null 6 null

F

sae info sad

null 7 null

G

sae info sad

null 4 null

sae info sad

null 5 null

sae info sad

2

B

D Esae info sad

3

C

sae info sad

1

A

Configuração da Árvore até o momento

sae info sad

null 6 null

F

sae info sad

null 7 null

G

sae info sad

null 4 null

sae info sad

null 5 null

sae info sad

2

B

D Esae info sad

3

C

sae info sad

1

A

1

2 3

75 64

Exemplo

Usando as funções inicializa() e criaNo(), crie uma estrutura que represente a seguinte árvore:

1

2 3

64 5

Exemplo

Usando as funções inicializa() e criaNo(), crie uma estrutura que represente a seguinte árvore:

Arvore *D = criaNo(4, inicializa(), inicializa());Arvore *E = criaNo(5, inicializa(), inicializa());Arvore *F = criaNo(6, inicializa(), inicializa());Arvore *B = criaNo(2, inicializa(), D);Arvore *C = criaNo(3, E, F);Arvore *A = criaNo(1, B, C);

1

2 3

64 5

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1, 2, 4, 5, 3, 6 e 7

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

/* verifica se a arvore está vazia. */int estaVazia(Arvore* a){ return a == NULL;}

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

a

1

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

a

1

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

a

1 2

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

a

1 2

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

a

1 2 4

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

a

1 2 4

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

a

1 2 4

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

a

1 2 4

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6 7

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6 7

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6 7

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6 7

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6 7

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6 7

a

null

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6 7

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6 7

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6 7

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6 7

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6 7

a

Analisando a chamada da função main:

imprime(A);

/* imprime a informação de todos os nós da árvore. */void imprime(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprime(a->sae); /* mostra sae */ imprime(a->sad); /* mostra sad */ }}

1

2 3

75 64

1 2 4 5 3 6 7

a

Fim! Volta para a chamada externa.

Percurso em Árvores Binárias

Uma das operações básicas relativas à manipulação de árvores é a visita sistemática a cada um dos seus nós.

Para percorrer a árvore deve-se, então, visitar cada um de seus nós. Visitar um nó significa operar com a informação do nó. Por exemplo: imprimir (conforme analisado anteriormente), atualizar informações, etc.

Percurso em Árvores Binárias

Temos duas categorias de percurso:

Percurso em profundidade: Corresponde a visitar um nó raiz e explora tanto quanto possível cada um dos seus

ramos, antes de retroceder.

Percurso em largura: Corresponde a visitar cada nó começando o nível mais baixo (ou mais alto) e movendo para baixo (ou para cima) nível a nível, visitando nós em cada nível da esquerda para direita (ou da direita para a esquerda).

Percurso em Profundidade

Pré-ordem:

Visitar a raizPercorrer a sub-árvore esquerda em pré-

ordemPercorrer a sub-árvore direita em pré-ordem

In-ordem:

Percorrer a sub-árvore esquerda em in-ordemVisitar a raizPercorrer a sub-árvore direita em in-ordem

Pós-ordem:

Percorrer a sub-árvore esquerda em pós-ordem

Percorrer a sub-árvore direita em pós-ordem Visitar a raiz

Percurso em Profundidade: Pré-Ordem

Visitar a raizPercorrer a sub-árvore esquerda em pré-

ordemPercorrer a sub-árvore direita em pré-ordem

Percurso: A B D G C E H I F

* A função Imprime analisada anteriormente usou o percurso Pré-Ordem.

A

B C

F

G

ED

IH

Percurso em Profundidade: Pré-Ordem

Visitar a raizPercorrer a sub-árvore esquerda em pré-

ordemPercorrer a sub-árvore direita em pré-ordem

/* imprime todos os nós da árvore em Pre-Ordem. */void imprimePre(Arvore* a){ if(!estaVazia(a)){ printf("%d ", a->info); /* mostra raiz */ imprimePre(a->sae); /* mostra sae */ imprimePre(a->sad); /* mostra sad */ }}

Percurso em Profundidade: In-Ordem

Percorrer a sub-árvore esquerda em in-ordemVisitar a raizPercorrer a sub-árvore direita em in-ordem

Percurso: D G B A H E I C F

A

B C

F

G

ED

IH

Percurso em Profundidade: In-Ordem

Percorrer a sub-árvore esquerda em in-ordemVisitar a raizPercorrer a sub-árvore direita em in-ordem

/* imprime todos os nós da árvore em In-Ordem. */void imprimeIn(Arvore* a){ if(!estaVazia(a)){ imprimeIn(a->sae); /* mostra sae */ printf("%d ", a->info); /* mostra raiz */ imprimeIn(a->sad); /* mostra sad */ }}

Percurso em Profundidade: Pós-Ordem

Percorrer a sub-árvore esquerda em pós-ordem

Percorrer a sub-árvore direita em pós-ordem Visitar a raiz

Percurso: G D B H I E F C A

A

B C

F

G

ED

IH

Percurso em Profundidade: Pós-Ordem

Percorrer a sub-árvore esquerda em pós-ordem

Percorrer a sub-árvore direita em pós-ordem Visitar a raiz

/* imprime todos os nós da árvore em Pos-Ordem. */void imprimePos(Arvore* a){ if(!estaVazia(a)){ imprimePos(a->sae); /* mostra sae */ imprimePos(a->sad); /* mostra sad */ printf("%d ", a->info); /* mostra raiz */ }}

Exercícios de Percurso em Profundidade

1. Usando as funções inicializa() e criaNo(), crie uma estrutura que represente a seguinte árvore:

2. Indique o percurso em pré-ordem, in-ordem e pós-ordem.

20

10 30

96 1814

25 338 15

Exercícios de Percurso em Profundidade

Arvore *H = criaNo(6, inicializa(), inicializa());Arvore *I = criaNo(9, inicializa(), inicializa());Arvore *J = criaNo(14, inicializa(), inicializa());Arvore *K = criaNo(18, inicializa(), inicializa());Arvore *D = criaNo(8, H, I);Arvore *E = criaNo(15, J, K);Arvore *F = criaNo(25, inicializa(), inicializa());Arvore *G = criaNo(33, inicializa(), inicializa());Arvore *B = criaNo(10, D, E);Arvore *C = criaNo(30, F, G);Arvore *A = criaNo(20, B, C);

Pré-Ordem:20, 10, 8, 6, 9, 15, 14, 18, 30, 25 e 33In-Ordem: 6, 8, 9, 10, 14, 15, 18, 20, 25, 30 e 33.Pós-Ordem:6, 9, 8, 14, 18, 15, 10, 25, 33, 30 e 20.

20

10 30

96 1814

25 338 15

Percurso em Largura

Lembando: Corresponde a visitar cada nó começando o nível mais baixo (ou mais alto) e movendo para baixo (ou para cima) nível a nível, visitando nós em cada nível da esquerda para direita (ou da direita para a esquerda).

Percurso: A, B, C, D, E, F, G, H e I

A

B C

F

G

ED

IH

Percurso em Largura

Para exemplificar, o percurso será de cima para baixo e da esquerda para direita usando uma fila:

Quando um nó é visitado, seus filhos (se houver) são colocados no final da fila.

Nó no início da fila é visitado.

A

B C

F

G

ED

IH

Percurso em Largura

A B C

B C C D

C D D E F

Visita A – insere B e C na fila

Visita B – insere D na fila

Visita C – insere E e F na fila

E F GVisita D – insere G na filaD E F

F G H IVisita E – insere H e I na filaE F G

G H IVisita F F G H I

G H I Visita G H I

H I Visita H I

I Visita I

A

B C

F

G

ED

IH

FILA FILA

top related