árvores: conceitos e binárias
TRANSCRIPT
Árvores - Conceitos e binária
Prof: Sergio Souza Costa
Sobre mim
Sérgio Souza CostaProfessor - UFMADoutor em Computação Aplicada (INPE)
https://sites.google.com/site/profsergiocosta/home
https://twitter.com/profsergiocosta
http://gplus.to/sergiosouzacosta
http://www.slideshare.net/skosta/presentations?order=popular
Árvores Conceitos
Árvores
• Estrutura não linear
• Hieráquica
• Recursiva
Árvores
• Nodos interligados de maneira hierárquica
• Nodo superior (raiz / pai), apontando para os seus nodos filhos (folhas / filho).
Analogia no mundo real
• Estrutura organizacional de uma empresa– Departamentos, setores, seções, etc.
• Organização de um livro– Partes, capítulos, seções, parágrafos
Mais exemplosEstrutura de um arquivo HTML
Mais exemplosHierarquia de diretorios e arquivos
Representação
Tipos de nodos (nós)
raiz
folha
nodos interno
Definições
• Raíz: um nodo sem pai
• Nodo: um elemento qualquer
• Folha: um nó que possui grau zero, ou seja, suas subárvores são vázia.
• Sub-árvore: formada por todos os nodos filhos a partir de um nodo qualquer
Definição geral
• Um nodo sem filhos e sem pai é uma árvore vazia.
• Um nodo com qualquer número de subárvores descendentes é uma árvore
Esquema Geral
R
raiz
Subárvores
...
Sub-árvores
Sub-árvore: é aquela que se forma a partir de um determinado nó.
A árvore A possui 2 sub-árvores:
A = {B, C }
Árvore C possui 3 sub-árvores:
C = {D, E, F}
OndeD = {G,H}F = {I}
Exemplo
Exemplo
Exemplo
Exemplos de árvores
Caminho em árvore
Sequencia de nodos ligando dois outros nodos quaisquer.
Caminho em árvore
• Nota: Só existe um caminho desde a raiz até um determinado nó.
Altura de uma árvore
• Altura é o tamanho do maior caminho desde a raiz até uma folha
Altura de uma árvorealtura 3
altura 2
altura 1
altura 0
Altura de uma árvore
• A altura da raiz é 0.
• Por definição, a altura de uma árvore vazia é -1.
Grau de uma árvore
• O grau de uma árvore é dado pela quantidade de descendentes permitido a cada nodo.
Exemplo de árvore de grau 4
Exemplo de árvore de grau 2
+
1 *
6 2
Árvores Binárias
Árvores Binárias • Árvore binária é um caso especial de árvore em que nenhum
nodo tem grau superior a 2, isto é, nenhum nodo tem mais que dois filhos.
– Adicionalmente, para árvores binárias existe um "senso de posição", ou seja, distingue-se entre uma subárvore esquerda e uma direita. Exemplos
a
b
a
b
a
b c
Árvores Binárias• Uma árvore binária é uma árvore que
pode ser nula, ou então tem as seguintes características:– existe um nodo especial denominado raiz;– os demais nodos são particionados em T1, T2
estruturas disjuntas de árvores binárias;– T1 é denominada subárvore esquerda e T2,
subárvore direita da raiz.
Árvores Binárias• Uma árvore binária é uma árvore que
pode ser nula, ou então tem as seguintes características:– existe um nodo especial denominado raiz;– os demais nodos são particionados em T1, T2
estruturas disjuntas de árvores binárias;– T1 é denominada subárvore esquerda e T2,
subárvore direita da raiz.Observem a
recursividade na
sua definição
ExemploChaves de campeonatos
ÁRVORE BINÁRIA - EXEMPLOChaves de campeonatos
Terminologias
Árvore estritamente binária: cada nó tem grau 0 ou 2, ou seja, todo nó tem 0 ou 2 filho
a) b)
a) b)
Terminologias
Árvore estritamente binária: cada nó tem grau 0 ou 2, ou seja, todo nó tem 0 ou 2 filho
TerminologiasÁrvore binária completa é uma árvore
estritamente binária na qual todo nó que apresente alguma sub-árvore vazia está localizado no último ou no penúltimo nível da árvore
a) b)
TerminologiasÁrvore binária completa é uma árvore
estritamente binária na qual todo nó que apresente alguma sub-árvore vazia está localizado no último ou no penúltimo nível da árvore
a) b)
TerminologiasÁrvore binária cheia quando todos os nós internos
tem grau 2 e todas as folhas estão no mesmo nível
a) b)
TerminologiasÁrvore binária cheia quando todos os nós internos
tem grau 2 e todas as folhas estão no mesmo nível
a) b)
Percurso em Árvores
Percurso em árvore binária
• Pré-ordem: visita a raiz, depois a sub-árvore da esquerda e depois direita.
• Em-ordem: visita a sub-árvore esquerda, depois a raiz, e finalmente a sub-árvore direita.
• Pós-ordem: visita a sub-árvore da esquerda, depois da direita e por ultimo imprime a raiz.
Exemplo de percurso pré-ordem
+
1 *
6 2
+1*62
Exemplo de percurso em-ordem
+
1 *
6 2
1+6*2
Exemplo de percurso pós-ordem
+
1 *
6 2
162*+
Exemplo de percurso pós-ordem
+
1 *
6 2
162*+Um algoritmo de
percurso pós-
ordem converte
notação infixa
para posfixa
Arvore Binária: TDA
• Tipo de dados abstrato da árvore binária:
Vazia: () → A// elemento, arvore esquerda direita Nodo: E × SAE × SAD → A
Arvore Binária: TDA
• Tipo de dados abstrato da árvore binária:
Vazia: () → A// elemento, arvore esquerda direita Nodo: E × SAE × SAD → A
Que árvore é essa ?A = Nodo (5, Vazia,
Nodo (8, Nodo (4, Vazia, Vazia),
Vazia)))
Arvore Binária: TDA
• Tipo de dados abstrato da árvore binária:
Vazia: () → A// elemento, arvore esquerda direita Nodo: E × SAE × SAD → A
Que árvore é essa ?A = Nodo (5, Vazia,
Nodo (8, Nodo (4, Vazia, Vazia),
Vazia)))
5
8
4
Árvore vazia
Arvore Binária: TDA
• Operações acessoras:
sae:: A → A // retorna a subarvore esquerdasad:: A → A // retorna a subarvore direitaelement :: A → E // retorno o elemento do nó
Exercício
A = Nodo (5, Nil, Nodo (8, Nodo (4, Vazia, Vazia), Vazia)))
B = sae (A) C = sad (A) D = sae(C) X = element (D)Y = element (A)
Exercício
A = Nodo (5, Nil, Nodo (8, Nodo (4, Vazia, Vazia), Vazia)))
B = sae (A) C = sad (A) D = sae(C) X = element (D)Y = element (A)
5
8
4
A
Exercício
A = Nodo (5, Nil, Nodo (8, Nodo (4, Vazia, Vazia), Vazia)))
B = sae (A) C = sad (A) D = sae(C) X = element (D)Y = element (A)
5
8
4
A
B
Exercício
A = Nodo (5, Nil, Nodo (8, Nodo (4, Vazia, Vazia), Vazia)))
B = sae (A) C = sad (A) D = sae(C) X = element (D)Y = element (A)
5
8
4
A
B
C
Exercício
A = Nodo (5, Nil, Nodo (8, Nodo (4, Vazia, Vazia), Vazia)))
B = sae (A) C = sad (A) D = sae(C) X = element (D)Y = element (A)
5
8
4
A
B
C
D
Exercício
A = Nodo (5, Nil, Nodo (8, Nodo (4, Vazia, Vazia), Vazia)))
B = sae (A) C = sad (A) D = sae(C) X = element (D)Y = element (A)
5
8
4
AA
B
C
D
Exercício
A = Nodo (5, Nil, Nodo (8, Nodo (4, Vazia, Vazia), Vazia)))
B = sae (A) C = sad (A) D = sae(C) X = element (D)Y = element (A)
5
8
4
AA
B
C
D
Exercícios resolvidos
• Ainda sem codificar em C a nossa árvore, faremos os seguintes exercícios.
• Podem fazer no papel ou bloco de notas, não precisem compilar (apenas mentalmente).
• Usando recursividade e apenas as quatro operações vistas anteriormente, vamos fazer os seguintes exercícios.
Exercícios resolvidos
1. Some os valores dos elementos de uma arvore binária
int soma (ArvBin *a) { if (a == Vazia()) return 0;
}
Exercícios resolvidos
1. Some os valores dos elementos de uma arvore binária
int soma (ArvBin *a) { if (a == Vazia()) return 0;
return elem(a) + soma (sae(a)) + soma (sad(a));
}
Exercícios resolvidos
1. Retorne a altura de uma árvore binaria. Onde a Altura é o tamanho do maior caminho desde a raiz até uma folha. Por definição, a altura de uma árvore vazia é -1.
int altura(ArvBin *a) {
}
Exercícios resolvidos
1. Retorne a altura de uma árvore binaria. Onde a Altura é o tamanho do maior caminho desde a raiz até uma folha. Por definição, a altura de uma árvore vazia é -1.
int altura(ArvBin *a) { if (a == Vazia())
return -1;
}
Exercícios resolvidos
1. Retorne a altura de uma árvore binaria. Onde a Altura é o tamanho do maior caminho desde a raiz até uma folha. Por definição, a altura de uma árvore vazia é -1.
int altura(ArvBin *a) { if (a == Vazia())
return -1;return maior(
altura (sae (a)), altura (sad (a))
) + 1;}
Exercícios resolvidos
1. Retorne a altura de uma árvore binaria. Onde a Altura é o tamanho do maior caminho desde a raiz até uma folha. Por definição, a altura de uma árvore vazia é -1.
int altura(ArvBin *a) { if (a == Vazia())
return -1;return maior(
altura (sae (a)), altura (sad (a))
) + 1;}
Exercícios resolvidos
1. Retorne a altura de uma árvore binaria. Onde a Altura é o tamanho do maior caminho desde a raiz até uma folha. Por definição, a altura de uma árvore vazia é -1.
int altura(ArvBin *a) { if (a == Vazia())
return -1;return maior(
altura (sae (a)), altura (sad (a))
) + 1;}
int maior (int v1, int v2) { if (v1 > v2) return v1 ; else return v2; }
Codificação
• A árvore binária é representado pela estrutura abaixo.
typedef struct ArvBin { int elem; struct ArvBin *sae; struct ArvBin *sad;} ArvBin;
Codificação
• Operações construtoras
ArvBin* Vazia () {return NULL;
}
ArvBin* Nodo (int elem, ArvBin* sae, ArvBin* sad ) { ArvBin* a = (ArvBin*)malloc (sizeof (ArvBin)); a->elem = elem; a->sad = sad; a->sae = sae; return a;}
Codificação
• Operações construtoras
ArvBin* Vazia () {return NULL;
}
ArvBin* Nodo (int elem, ArvBin* sae, ArvBin* sad ) { ArvBin* a = (ArvBin*)malloc (sizeof (ArvBin)); a->elem = elem; a->sad = sad; a->sae = sae; return a;}
Codificação
• Operações construtoras
ArvBin* Vazia () {return NULL;
}
ArvBin* Nodo (int elem, ArvBin* sae, ArvBin* sad ) { ArvBin* a = (ArvBin*)malloc (sizeof (ArvBin)); a->elem = elem; a->sad = sad; a->sae = sae; return a;}
Codificação
• Operações construtoras
ArvBin* Vazia () {return NULL;
}
ArvBin* Nodo (int elem, ArvBin* sae, ArvBin* sad ) { ArvBin* a = (ArvBin*)malloc (sizeof (ArvBin)); a->elem = elem; a->sad = sad; a->sae = sae; return a;}
Codificação
• Operações construtoras
ArvBin* Vazia () {return NULL;
}
ArvBin* Nodo (int elem, ArvBin* sae, ArvBin* sad ) { ArvBin* a = (ArvBin*)malloc (sizeof (ArvBin)); a->elem = elem; a->sad = sad; a->sae = sae; return a;}
Codificação
• Operações retornar os atributos da árvore.
int elem (ArvBin* b) { return b->elem;}
ArvBin* sae (ArvBin* b) { return b->sae;}
ArvBin* sad (ArvBin* b) { return b->sad;}
Codificação
• Código para visualizar uma árvore binária “deitada”
void mostra (ArvBin *a, int n) { if (a) { int i; mostra (sad(a), n+1); for (i = 0; i < n; i++) printf ("\t"); printf ("%d\n", elem(a)); mostra (sae(a), n+1); }}
Visualização
23
35
28
15
r
Árvore binária - Aplicações
• Uma importante aplicação das árvores binárias é para a realização de buscas.
• O que as árvores abaixo tem em comum?
K
A P
N R
13
10 25
20 31
29
2 12
Árvore Binária De Busca
• Operações básicas– Insere elemento– Busca– Remoção
INSERÇÃO
• Para adicionar um elemento x – Se a árvore estiver vazia, adicione um novo
nó contendo o elemento x– Se a raiz é maior que x então insira x na
subárvore esquerda, caso contrário – insira x na subárvore direita
Inserir
Inserir 23
Inserir
23Inserir 23
Inserir
23Inserir 23
nil nil
Inserir
23Inserir 23Inserir 15
nil nil
Inserir
23Inserir 23Inserir 15
15
nil nil
Inserir
23Inserir 23Inserir 15
15
nil nil
nil nil
Inserir
23Inserir 23Inserir 15
15
nil
nil nil
Inserir
23Inserir 23Inserir 15Inserir 35
15
nil
nil nil
Inserir
23Inserir 23Inserir 15Inserir 35
15
nil
35
nil nil
Inserir
23Inserir 23Inserir 15Inserir 35
15
nil
35
nil nilnil nil
Inserir
23Inserir 23Inserir 15Inserir 35
15 35
nil nilnil nil
Inserir
23Inserir 23Inserir 15Inserir 35Inserir 28
15 35
nil nilnil nil
Inserir
23Inserir 23Inserir 15Inserir 35Inserir 28
15 35
28
nil nilnil nil
Inserir
23Inserir 23Inserir 15Inserir 35Inserir 28
15 35
28
nil nil nil nil
nil nil
Inserir
23Inserir 23Inserir 15Inserir 35Inserir 28
15 35
28
nil nil
nilnil nil
Inserir - Código
ArvBin *insere (ArvBin *r, int x) { if (r == NULL) r = Nodo (x, NULL, NULL); else if (x < elem(r) ) r->sae = insere(sae(r), x ) ; else r->sad = insere(sad(r), x ) ; return r;}
23
15 35
28
nil nil nil
nil nil
arv = insere(arv, 23); arv = insere(arv, 15); arv = insere(arv, 35); arv = insere(arv, 28);
Testando - Inserir
Busca
• Para encontrar um elemento x – Se x é a raiz então x foi encontrado, caso
contrário– Se x é menor que a raiz então procure x na
sub-árvore esquerda, caso contrário– Procure x na sub-árvore direita de– Se a árvore é vazia então a busca falha
Buscar
23Há um 28 armazenado?
15 35
28
nil nil nil
nil nil
Buscar
23Há um 28 armazenado?
15 35
28
28 > 23
nil nil nil
nil nil
Buscar
23Há um 28 armazenado?
15 35
28
28 < 35
nil nil nil
nil nil
Buscar
23Há um 28 armazenado?
15 35
28encontrou
nil nil nil
nil nil
Código - Buscar
ArvBin* busca (ArvBin *r, int x) { if ((!r) || (elem(r) == x)) return r; else { if (elem(r) < x) return busca(sad(r),x); else return busca(sae(r),x); }}
Parada: Achou o elemento ou o elemento não se encontra na arvore.