Árvores binárias marco antonio montebello júnior [email protected] estrutura de dados

54
Árvores Binárias Marco Antonio Montebello Júnior [email protected] Estrutura de Dados

Upload: internet

Post on 16-Apr-2015

103 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Árvores Binárias

Marco Antonio Montebello Jú[email protected]

Estrutura de Dados

Page 2: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Fundamentos sobre árvores

Uma árvore é um conjunto finito de n >= 0 nós Se n = 0 temos uma árvore nula Se n > 0 temos uma árvore com as seguintes

características: Existe um nó especial chamado raiz; Os demais são particionados em T1, T2, . . ., Tk

estruturas disjuntas de árvores As estruturas T1, T2, . . ., Tk denominam-se árvores

Page 3: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Conceitos importantes sobre árvores

A. Grau Representa o número de subárvores de um nó.

B. Nó folha ou terminal É o nó que possui grau 0, ou seja, não possui subárvores.

C. Grau de uma árvore (n-aridade) É definido como sendo igual ao máximo dos graus de todos

os seus nós.

D. Nós filhos São as raízes das subárvores de um nó. E este nó é o pai

delas.

Page 4: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Conceitos importantes sobre árvores

E. Nós irmãos São os nós filhos que apresentam o mesmo pai (existem ainda

nó ancestral, descendente, descendente esquerdo ou direito);

F. Nível A raiz da árvore tem nível 0 (em alguns livros é considerado

igual à 1). Qualquer outro nó apresenta um nível a mais que seu nó pai

G. Altura (em alguns livros é profundidade) É o máximo dos níveis de todos os nós da árvore. Isso

equivale ao tamanho do passeio mais distante da raiz até qualquer folha

Page 5: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Conceitos importantes sobre árvores

Page 6: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Conceitos importantes sobre árvores

Conceito Valor

A

B

C

D

E

F

G

Page 7: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Conceitos importantes sobre árvores

Conceito Valor

A Nó ‘a’ grau 3. Nó ‘h’ grau 2

B ‘e’, ‘g’, ‘k’, ‘l’, ‘m’, ‘i’, e ‘j’

C Grau 4

D ‘z’, ‘e’, ‘f’ e ‘g’ filhos ‘b’. ‘b’ filho ‘a’

E ‘z’, ‘e’, ‘f’ e ‘g’ mesmo pai ‘b’

F ‘b’, ‘c’ e ‘d’ nível 1. ‘z’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’ e ‘j’ nível 2. ‘k’, ‘l’ e ‘m’ nível 3

G Altura: 4

Page 8: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Árvores Binárias

É uma árvore que pode ser nula, ou então apresentar as seguintes características: Um nó especial chamado raiz; Os demais nós são particionados em T1, T2

estruturas disjuntas de árvores binárias; A estrutura T1 é chamada subárvore esquerda e T2

subárvore direita da raiz.

Page 9: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Árvores Binárias

Árvore binária estritamente binária Ocorre quando todo nó que não é folha, tiver

subárvores esquerda e direita não vazias. Uma árvore estritamente binária com n folhas contém sempre 2n - 1 nós

Árvore binária completa É uma árvore estritamente binária de profundidade

(altura) d, cujas folhas estejam no nível n. Considerando tn como o número total de nós numa árvore binária completa de profundidade d, observamos a seguinte relação : tn = 2d - 1

Page 10: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Observações importantes

Observamos que uma árvore binária é um caso especial de árvore cujos nós não têm grau superior a 2

Nenhum nó tem mais do que dois filhos Existe um forte senso de posição pela existência

de uma subárvore direita e esquerda Cada subárvore caracteriza uma definição

recursiva

Page 11: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Observações importantes

Será que as árvores binárias apresentadas abaixo são iguais ou distintas? Por que?

Exemplo de duas árvores binárias com subárvores nulas

Page 12: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Observações importantes

Um exemplo de árvore estritamente binária

Page 13: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Observações importantes

Um exemplo de árvore binária completa de nível 3 e altura 4

Page 14: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Árvores de Busca Binárias

Marco Antonio Montebello Jú[email protected]

Estrutura de Dados

Page 15: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Árvores de busca binária

É aquela que tem a propriedade de todos os elementos na subárvore esquerda de um nó n serem menores que o conteúdo de n, e todos os elementos na subárvore direita de n serem maiores ou iguais ao conteúdo do nó n

Page 16: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Árvores de busca binária

Dessa forma, podemos realizar as seguinte observações: Todo elemento armazenado na subárvore esquerda é

menor que n; Nenhum elemento armazenado na subárvore direita é

menor que n; As subárvores esquerda e direita também são árvores

de busca binária A definição de árvore de busca binária também é

recursiva

Page 17: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Árvores de busca binária

Abaixo está o exemplo de uma árvore de busca binária e uma árvore que não pode ser considerada como tal.

Árvores Binárias ordenada Árvore Binária não ordenada

(busca binária)

Page 18: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Mais um Exemplo de Árvore de Busca Binária Veja mais um exemplo de árvore de busca binária, dessa vez, com valores

numéricos e considerando a seguinte seqüência de entrada : 14, 15, 4, 9, 7, 18, 3, 5, 16, 4, 20, 17, 9, 14 e 5.

Page 19: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Outro exemplo

Uma outra aplicação é a representação de uma expressão contendo operandos e operadores

A + B * C (A + B) * C

Page 20: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Operações básicas em árvores de busca binária

Representando um nó:

struct arv

{

char obj;

struct arv *esq, *dir;

};

typedef struct arv *AVRPTR;

Page 21: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Operações básicas em árvores de busca binária

Uma árvore binária de busca binária vazia é representada por uma variável ponteiro nula

A utilização de uma lista encadeada tem a vantagem de não necessitar nenhuma movimentação de dados quando um novo elemento precisa ser inserido

Basta o ajuste adequado dos ponteiros para colocar o novo elemento na posição adequada

Observamos que a inserção de elementos novos é ainda mais eficiente porque eles entram sempre na condição de folhas, pois, um nó não pode entrar numa árvore e já “assumir” filhos

Page 22: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Operações básicas em árvores de busca binária

Abaixo está a estrutura de representação interna de uma árvore de busca binária na memória:

Representação interna de árvore binária

Page 23: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Inserção de um elemento numa árvore de busca binária

Acompanhe as operações de inserção realizadas na árvore de busca binária, para observar que basta movimentar adequadamente os ponteiros para a realização das inserções

Page 24: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Inserção de um elemento numa árvore de busca binária

Page 25: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Observações sobre a inserção de elementos numa árvore de busca binária

Observando os exemplos anteriores, podemos considerar que a inserção é uma operação trivial

Basta verificar se a árvore não está vazia, em seguida, se o novo elemento é menor do que a raiz, a inserção é na subárvore esquerda, caso contrário, a inserção é na árvore direita

Page 26: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Exemplo de uma rotina para inserir elementos numa árvore binária de busca

void tins(AVRPTR *plist, char x){

if((*plist)== NULL){

*plist=(AVRPTR) malloc(sizeof(struct arv));(*plist)->obj= x;(*plist)->esq=NULL;(*plist)->dir=NULL;

}else{

if(x<(*plist)->obj)tins(&((*plist)->esq),x);

elsetins(&((*plist)->dir),x);

}}

Page 27: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Pesquisa de um elemento

T é uma árvore nula Não fazemos nada

A raiz de T armazena o elemento X A solução é imediata

X é menor que o valor da raiz de T Prossegue-se com a busca na subárvore esquerda de

T X é maior ou igual à T

Prossegue-se com a busca na subárvore direita de T

Page 28: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Exemplo de uma rotina para pesquisar um elemento numa árvore de busca binária

AVRPTR tfnd(AVRPTR *plist, char x){ if(*plist==NULL)/*elemento nao encontrado*/ return (NULL); else if(x==(*plist)->obj)/*elem. encontrado na raiz*/ return(*plist); else if(x<(*plist)->obj)/*procura-o numa subarvore*/ return(tfnd(&((*plist)->esq),x)); else return(tfnd(&((*plist)->dir),x));}

Page 29: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Pesquisa de um elemento

Quando os elementos que a árvore armazena estão distribuídos de forma equilibrada em todas as subárvores, a busca binária aproxima-se muito, em eficiência, da busca binária realizada em tabelas seqüenciais.

Por que?

Page 30: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Remoção de um elemento

A raiz não possui filhos A solução é imediata. Podemos removê-la e anular T

A raiz possui um único filho Podemos remover o nó raiz, substituindo-o pelo seu

nó filho; A raiz possui dois filhos

Não é possível que os dois filhos assumam o lugar do pai; escolhemos então o nó que armazena o maior elemento na subárvore esquerda de T, este nó será removido e o elemento armazenado por ele entrará na raiz da árvore T

Page 31: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Exemplo de uma rotina para remover um elemento numa árvore de busca binária

AVRPTR getmax(AVRPTR *plist){ AVRPTR t; t = *plist; if(t->dir == NULL) { *plist = (*plist)->esq; return(t); } else return(getmax(&((*plist)->dir)));}

Page 32: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Exemplo

p = getmax(&(t->esq));/*desliga o nó com maior valor*/

t->obj = p->obj;/*armazena o valor na raiz da árvore*/

free(p);

Page 33: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Uma rotina de remoção mais genérica

A rotina tRem( ) é essencialmente igual àquele utilizado para pesquisa

A diferença é que, caso o elemento seja encontrado (na raiz da árvore), ele será removido

Page 34: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Uma rotina de remoção mais genéricaint tRem(AVRPTR *plist, char *x){ AVRPTR p; if(*plist == NULL) return(1); /*elemento não encontrado*/ if((*x == (*plist)->obj) == 1) /*elem. encontrado na raiz*/ { p = *plist; if((*plist)->esq == NULL) *plist = (*plist)->dir; /*raiz nao tem filho esq.*/ else if((*plist)->dir == NULL) *plist = (*plist)->esq; /*a raiz nao tem filho dir.*/ else /*a raiz tem ambos os filhos*/ { p = getmax(&((*plist)->esq)); (*plist)->obj=p->obj; } free(p); printf("\nElemento achado e removido!!!"); } else if((*x<(*plist)->obj) == 1) tRem(&((*plist)->esq), x); /*procura na subarvore esq.*/ else tRem(&((*plist)->dir), x); /*procura na subarvore dir.*/}

Page 35: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Passeio em Árvores Binárias

Marco Antonio Montebello Jú[email protected]

Estrutura de Dados

Page 36: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Passeio em árvores binárias (percurso ou atravessamento)

Realizar um passeio numa árvore binária deve ser entendido como visitar de forma sistemática, cada um de seus nós, desenvolvendo um certo processamento.

Podemos considerar quatro tipos de passeios: Em-ordem Pré-ordem (também conhecido como passeio em

profundidade) Pós-ordem Em-nível

Page 37: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Facilitando a compreensão com uma analogia

Para facilitar a compreensão dos três primeiros tipos, vamos utilizar um analogia com as notações que uma expressão aritmética pode ser escrita : infixa, prefixa e pósfixa.

Considerando a expressão infixa A + B, podemos utilizar a seguinte representação:

+

A B

Page 38: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Analogia

A tabela abaixo ilustra as possibilidades de exibir os nós da árvore anterior:

Tipo da notação Seqüência Equivalência de passeio

Infixa

Exibir a folha esquerda (E)

Em-ordemExibir a raiz (R)

Exibir a folha direita (D)

Prefixa

Exibir a raiz (R)

Pré-ordemExibir a folha esquerda (E)

Exibir a folha direita (D)

Pósfixa

Exibir a folha esquerda (E)

Pós-ordemExibir a folha direita (D)

Exibir a raiz (R)

Page 39: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Resolva:

B

AC

Formas de Passeio Saídas

Em-ordem (ERD)

Pré-ordem (RED)

Pós-ordem (EDR)

Page 40: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Resultado

B

AC

Formas de Passeio Saídas

Em-ordem (ERD) A, B, C

Pré-ordem (RED) B, A, C

Pós-ordem (EDR) A, C, B

Page 41: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Exemplo mais complexo de uma árvore binária com subárvores

Formas de Atravessamento

Saídas

Em-ordem (ERD)

Pré-ordem (RED)

Pós-ordem (EDR)

D

B E

A CF

Page 42: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Resultado

Formas de Atravessamento

Saídas

Em-ordem (ERD) A, B, C, D, E, F

Pré-ordem (RED) D, B, A, C, E, F

Pós-ordem (EDR) A, C, B, F, E, D

D

B E

A CF

Page 43: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Observações importantes

Pela análise na figura da representação da expressão A + B como árvore binária e a analogia realizada a partir dela, percebemos que a seqüência básica de acesso ERD pode ser generalizada

Na verdade, cada subárvore não precisa se restringir a uma única folha: Exibir a subárvore esquerda (E) Exibir a raiz (R) Exibir a subárvore direita (D)

+

A B

Page 44: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Observações importantes

Podemos observar que a seqüência ERD tornou-se recursivas

Ambas as subárvores devem ser impressas também em-ordem e a recursão pára quando chegamos a subárvores nulas

As seqüências pré-ordem e pós-ordem podem ser generalizadas segundo o mesmo raciocínio

+

A B

Page 45: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Rotina para passeio em-ordem

void emordem(AVRPTR t){if(t != NULL){

emordem(t->esq);printf(" %c,",t->obj);emordem(t->dir);

}}

Page 46: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Rotina para passeio em pré-ordem

void preordem(AVRPTR t){if(t != NULL){

printf(" %c,",t->obj);preordem(t->esq);preordem(t->dir);

}}

Page 47: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Rotina para passeio em pós-ordem

void posordem(AVRPTR t){if(t != NULL){

posordem(t->esq);posordem(t->dir);printf(" %c,",t->obj);

}}

Page 48: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

O passeio tipo em-nível

Parece ser o de mais fácil compreensão Entretanto, sua implementação é a mais complexa. Supondo que ele fosse aplicado à árvore da figura

abaixo, obteríamos s seqüência : D, B, E, A, C, F Observe que agora os nós são acessados, por nível, da

esquerda para a direitaD

B E

AC F

Page 49: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Desenvolvendo um algoritmo para o passeio em-nível

Podemos usar uma fila contendo inicialmente apenas o nós raiz

A partir daí, enquanto a fila não se tornar vazia, retiramos dela um nós cujos filhos deverão ser colocados na fila, aí então, o nó retirado da fila pode ser exibido

Como podemos observar, a rotina emnivel faz uso de uma fila

Também estão listadas as rotinas para implementar uma fila circular

Page 50: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Rotinavoid emnivel(AVRPTR t){

AVRPTR n;NODEPTR q;if(t != NULL){

qinit(&q);insert(&q,t);while (empty(&q) != 1){

n = remove(&q);if(n->esq != NULL)

insert(&q,n->esq);if(n->dir!=NULL)

insert(&q,n->dir);printf(" %c,", n->obj);

}}

}

Page 51: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Fila Circularvoid qinit(NODEPTR *pq){

*pq = NULL;}

void insert(NODEPTR *pq, AVRPTR x){

NODEPTR p;p =(NODEPTR) malloc(sizeof (struct fila));p->info=x;if(empty(pq) == 1)

*pq=p;else

p->next=(*pq)->next;(*pq)->next=p;*pq=p;

}

Page 52: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Fila CircularAVRPTR remove(NODEPTR *pq){

AVRPTR x;NODEPTR p;if(empty(pq) == 1){

printf("Underflow da fila\n");getch();exit(1);

}p = (*pq)->next;x = p->info;if(p == *pq) /*somente um no' na fila*/

*pq = NULL;else

(*pq)->next = p->next;free(p);return(x);

}

int empty(NODEPTR *pq){

return((*pq == NULL)?1:0);}

Page 53: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Destruição de uma árvore

A rotina tDestruir() utiliza o atravessamento pré-ordem e, para cada nó acessado, o processamento consiste numa comparação que avalia se o elemento armazenado pelo nó é aquele procurado.

Muitos outros algoritmos importantes no tratamento de árvores são baseados nestes tipos de atravessamento

Abaixo está o exemplo do algoritmo tDestruir( ), para destruir árvores

Ele utiliza um atravessamento do tipo pós-ordem, cujo processamento é a liberação do nó acessado

Page 54: Árvores Binárias Marco Antonio Montebello Júnior marco.antonio@aes.edu.br Estrutura de Dados

Estrutura de Dados

Destruição de uma árvore

void tDestruir(AVRPTR *plist){if(*plist != NULL){

tDestruir(&((*plist)->esq));/*libera subarvore esquerda*/ tDestruir(&((*plist)->dir));/*libera subarvore direita */free(*plist);

}}