Escolar Documentos
Profissional Documentos
Cultura Documentos
Centro de Informtica
Departamento de Informtica
Estrutura de Dados
rvores
} Tiago Maritan
} tiago@ci.ufpb.br
1
(
2
Recursividade
3
Recursividade Motivao
} Sabemos que uma funo pode chamar outras funes
} Ex: func1() chamando a func2()
void func2(){
printf("Na funo 2");
}
void func1(){
printf("Na funo1");
printf("Vou chamar a funo2");
func2();
printf("No fim da funo1");
}
4
Recursividade - Motivao
} Hoje veremos que uma funo pode chamar ela mesma
} Ex: func1() chamando a si mesma
void func1(){
printf("No inicio da funo1");
func1();
printf("No fim da funo1);
}
6
Funo Recursiva
} Exemplo1: Funo que retorna a soma de inteiros de1 e n
} Como funciona???
7
Funo Recursiva
} Exemplo1: Funo que retorna a soma de inteiros de1 e n
} Como funciona a chamada SomaAteN(4)?
SomaAteN(4)
4 + SomaAteN(3) 10
3 + SomaAteN(2) 6
2 + SomaAteN(1) 3
8
Funo Recursiva
} Exemplo 2: Funo fatorial
9
Funo Recursiva
} Exemplo1: Funo que retorna a soma de inteiros de1 e n
} Como funciona a chamada fatorial(4)?
fatorial(4)
4 * fatorial(3) 24
3 * fatorial(2) 6
2 * fatorial(1) 2
10
Quando usar recursividade?
} Quando o problema tem uma estrutura recursiva
} Ou seja, uma instncia do problema contm uma instncia
menor do mesmo problema.
} Ex: fatorial(n) = n*fatorial(n-1)
}
11
Observaes sobre Recursividade
} uma tcnica elegante e, geralmente, quem a utiliza
demonstra experincia,
12
)
13
rvores
14
O que uma rvore?
} Em Cincia da Computao, uma rvore um modelo
abstrato de uma estrutura hierrquica
rvores
} Uma rvore consiste de um conjunto de ns com uma
relao pai-filho (hierrquica).
} Aplicaes:
} Sistemas de arquivos
} Organogramas
} Ambientes de Programao
16
Terminologia de rvore
} Raiz: Primeiro n da rvore No contm um pai (A)
} N no-terminal: n com pelo menos um filho (A, B, C, F)
} N folha (ou n terminal) : n sem filhos (E, I, J, K, G, H,D)
B C D
E F G H
I J K
subtree
rvores Binrias
19
rvores Binrias
} um tipo de rvore, onde o grau
de cada n no mximo dois.
20
Implementao de rvores Binrias
21
Implementao de rvores Binrias
} Interface
} Criar uma rvore vazia;
} Verificar se a rvore est vazia ou no;
} Buscar um elemento na rvore;
} Inserir um n raiz;
} Inserir um filho direita de um n;
} Inserir um filho esquerda de um n;
} Esvaziar uma rvore;
} Exibir a rvore.
22
Implementao de rvores Binrias
/* Definio da Estrutura de Dados */
typedef struct no {
int conteudo; /* conteudo */
struct no *esq; /* ref. para filho da esquerda */
struct no *dir; /* ref. para filho da direita */
} tNo; /* tipo do n */
23
Implementao de rvores Binrias
/* Definio das Operaes */
24
Implementao de rvores Binrias
//Buscar um elemento na rvore
//Retorna o endereo se o elemento for
// encontrado, caso contrrio retorna NULL
tArvBin busca(tArvBin T, int dado) {
tArvBin achou;
if (T == NULL)
return NULL; // Arvore Vazia
if(T->conteudo == dado)
return T; //Elem. encontrado na raiz
return achou;
}
25
Implementao de rvores Binrias
// Insere um n raiz em uma rvore vazia
// Retorna 1 se a insero for com sucesso.
// Caso contrrio 0
int insereRaiz(tArvBin *T, int dado ) {
tNo *novoNo;
if (*T != NULL)
return (0); //Erro: rvore no est vazia
novoNo = malloc(sizeof(tNo));
if (novoNo == NULL) return 0; //Err: mem. Insuf.
novoNo->conteudo = dado;
novoNo->esq = NULL;
novoNo->dir = NULL;
*T = novoNo;
return 1;
}
26
Implementao de rvores Binrias
// Insere um filho direita de um dado n
// Retorna 1 se a insero for com sucesso,
// Caso contrrio 0
int insereDireita(tArvBin T, int vPai, int vFilho ) {
tNo *f, *p, *novoNo;
//Verifica se o elemento j no existe
f = busca(T, vFilho);
if (f != NULL) return 0; //Err: dado j existe
novoNo = malloc(sizeof(tNo));
if (novoNo == NULL)
return (0); //Err: mem. insuf.
novoNo->conteudo = vFilho;
novoNo->esq = NULL;
novoNo->dir = NULL;
p->dir = novoNo;
return 1;
}
28
Implementao de rvores Binrias
//Insere um filho esquerda de um dado n
//Retorna 1 se a insero for com sucesso,
// caso contrrio 0
int insereEsq(tArvBin T, int vPai, int vFilho ) {
tNo *f, *p, *novoNo;
//Verifica se o elemento j no existe
f = busca(T, vFilho);
if (f != NULL) return 0; //Err: dado j existe
novoNo = malloc(sizeof(tNo));
if (novoNo == NULL)
return (0); //Err: mem. insuf.
novoNo->conteudo = vFilho;
novoNo->esq = NULL;
novoNo->dir = NULL;
p->esq = novoNo;
return 1;
}
30
Caminhamento em
rvores Binrias
31
Caminhamento em rvores Binrias
} Ao de percorrer (visitar) todos os ns de uma rvore
} Cada n visitado uma nica vez.
B C
D E F
G H I
33
Caminhamento em rvores Binrias
} Esses mtodos de caminhamento em AVBin so
geralmente definidos de forma recursiva.
} Idia geral:
} Visitar a raiz, e
} Caminhar em suas sub-rvores esquerda e direita.
34
Caminhamento em Pr-ordem
} 1.Visite a raiz;
} 2. Caminhe na sub-rvore esquerda em pr-ordem;
} 3. Caminhe na sub-rvore direita em pr-ordem.
A
Sequncia de visitao dos
ns: ABDGCEHIF B C
D E F
G H I
35
Caminhamento em Pr-ordem
//Exibe o contedo de uma rvore em pr-ordem
void exibePreOrdem(tArvbin T) {
if (T == NULL)
return ;
printf(%d , T->conteudo);
if (T->esq != NULL)
exibePreOrdem(T->esq);
if (T->dir != NULL)
exibePreOrdem(T->dir);
36
Caminhamento em In-ordem
} 1. Caminhe na sub-rvore esquerda em in-ordem;
} 2.Visite a raiz.
} 3. Caminhe na sub-rvore direita em in-ordem;
A
Sequncia de visitao dos
ns: DGBAHEICF B C
D E F
G H I
37
Caminhamento em In-ordem
//Exibe o contedo de uma rvore em pr-ordem
void exibeInOrdem(tArvbin T) {
if (T == NULL)
return ;
if (T->esq != NULL)
exibeInOrdem(T->esq);
printf(%d , T->conteudo);
if (T->dir != NULL)
exibeInOrdem(T->dir);
38
Caminhamento em Ps-ordem
} 1. Caminhe na sub-rvore esquerda em ps-ordem;
} 2. Caminhe na sub-rvore direita em ps-ordem;
} 3.Visite a raiz.
A
Sequncia de visitao dos
ns: GDBHIEFCA B C
D E F
G H I
39
Caminhamento em Ps-ordem
//Exibe o contedo de uma rvore em pr-ordem
void exibePosOrdem(tArvbin T) {
if (T == NULL)
return ;
if (T->esq != NULL)
exibePosOrdem(T->esq);
if (T->dir != NULL)
exibePosOrdem(T->dir);
printf(%d , T->conteudo);
40
Caminhamento em rvores Binrias
} rvores binrias podem ser utilizadas para representar
expresses aritmticas.
41
Caminhamento em rvores Binrias
} Assim, a expresso A + B*C seria representada pela rvore:
+
A *
B C
} Enquanto que a expresso (A + B)*C seria representada como:
*
+ C
A B
42
rvores Ordenadas
} rvore ordenada: aquela na qual os filhos de cada n esto
ordenados.
} Assume-se ordenao da esquerda para a direita.
44
rvore Binria de Pesquisa
(ABP ou Arvore Binria de Busca)
} Arvores que so vazias ou que o n raiz contm uma chave e:
} Chaves da subrvore esquerda < chave da raiz.
} Chaves da subrvore direita > chave da raiz.
} Subrvores direita e esquerda so tambm ABP.
45
Implementao de ABPs
} Interface
} Criar uma rvore vazia;
} Verificar se a rvore est vazia ou no;
} Buscar um elemento na rvore;
} Inserir um n na rvore;
} Exibir a rvore;
46
Implementao de ABPs
/* Definio da Estrutura de Dados */
typedef struct no {
int info;
struct no *esq; /* n esquerdo */
struct no *dir; /* n direito */
} tNo; /* n da rvore */
47
Implementao de ABPs
/* Definio das Operaes */
48
Implementao de ABPs
//Buscar um elemento na rvore
//Retorna o endereo se o elemento for encontrado,
//Caso contrrio retorna NULL
tAbp busca(tAbp T, int dado) {
tAbp achou;
if (T == NULL) return NULL; //Err: arv. Vazia;
if(T->info == dado)
return T;
49
Implementao de ABPs
//Exibe o contedo de uma rvore no formato in-ordem
//(preserva a ordenao)
void exibe (tAbp T) {
if (T != NULL) {
exibe(T->esq);
printf(%d , T->info);
exibe(T->dir);
}
}
50
Implementao de ABPs
//Insere um n em uma rvore ABP
//Retorna 1 se a insero for com sucesso.
//Caso contrrio retorna 0
int insere (tAbp T, int item) {
tNo *novoNo, *atual, *p;
novoNo = malloc(sizeof(tno));
if (novoNo == NULL) return 0;
novoNo->info = item;
novoNo->esq = NULL;
novoNo->dir = NULL;
return 1;
}
52
Implementao de ABPs
// ou ... (insere em ABP no vazia)
53
rvore Binria de Pesquisa Balanceada
(AVL)
54
ABPs Desbalanceadas
} Inseres e remoes sucessivas em uma ABP podem
torn-las desequilibradas ou desbalanceadas.
} Sub-rvores da esquerda e direita tem alturas muito diferentes;
55
ABPs Balanceada
} Uma ABP dita balanceada quando:
} Para qualquer n, as sub-rvores esquerda e direita possuem a
mesma altura (ou alturas similares).
56
rvore Binria de Pesquisa Balanceada
} O balanceamento de uma rvore binria pode ser:
} Esttico
} Dinmico (AVL ou rvores Rubro-negras)
57
rvores AVL
} O termo AVL foi definido em homenagem aos matemticos
russos Adelson-Velskii e Landis.
58
rvores AVL
} Uma rvore AVL mais eficiente nas suas operaes de
busca do que uma ABP degenerada (ou desbalanceada),
} O no comparaes diminui sensivelmente.
59
Insero em rvores AVL
} O que pode acontecer quando um novo n inserido numa
rvore balanceada ?
60
Insero AVL
} Ex: Suponha a rvore abaixo:
FB = hD(n) hE(n)
62
Insero AVL
} Como manter ento uma rvore AVL aps as inseres?
63
Insero AVL - Rebalanceamento
} Caso 1: Raiz de uma subrvore tem FB = 2 (ou -2) e um
filho com FB = 1 (-1), e os dois tem o mesmo sinal
Exemplo1: Exemplo2:
Exemplo1:
10
8 15
4 9 12
65
Insero AVL - Rebalanceamento
} Rotao direita As subrvores T1, T2, T3 e T4
podem ser vazias ou no.
2 8
3 6 10
66
Insero AVL - Rebalanceamento
} Caso 2: Raiz de uma subrvore tem FB = 2 (ou -2) e um
filho com FB = 1 (-1), e os dois tem sinais opostos.
67
Insero AVL - Rebalanceamento
} Exemplo: 1 Rotao - N 4 rotacionado esquerda
68
Insero AVL - Rebalanceamento
} Dicas:
} FB positivo (+) a rotao para esquerda
} FB negativo (-) a rotao para direita
69
Remoo em rvore AVL
} A remoo mais complicada que a insero.
70
Remoo em rvore AVL
} 1) Remoo do n10
71
Remoo em rvore AVL
} 2) Remoo do n 40
72
Remoo em rvore AVL
Remoo do n: 10
73
Remoo em rvore AVL
Remoo do n: 40
74
Remoo em rvore AVL
} Existem situaes mais complexas.
} Balanceamento devido a retirada de um n de uma
subrvore, pode provocar um novo desequilbrio na rvore.
75
Remoo em rvore AVL
} Exemplo: Remoo do n 65
} Passo 1: Rotao simples esquerda entre 70 e 80
Esta rvore AVL?
A rvore no AVL,
pois |FB(60)|>1.
76
Remoo em rvore AVL
} Exemplo: Remoo do n 65
} Passo 2: Reaplicar o mtodo para o 60.
} Rotao exigida a dupla (esquerda no 40 + direita no 60)
77
Remoo em rvore AVL
} Isso mostra porque a remoo mais complicada que a
insero.
78
Concluses
} Balanceamento busca minimizar o nmero mdio de
comparaes necessrias para localizar qualquer dado.
79
Implementao de AVLs
} Interface
} Criar uma rvore vazia;
} Verificar se a rvore est vazia ou no;
} Buscar um elemento na rvore;
} Exibir a rvore;
} Inserir um n na rvore;
80
Implementao de AVLs
/* Definio da Estrutura de Dados */
typedef struct no {
int info;
int bal; /* fator de balanceamento */
struct no *esq;
struct no *dir;
} tNo;
81
Implementao de AVLs
//Insere um n em uma rvore AVL
//Retorna 1 se a insero for com sucesso
//Retorna 0, caso contrrio.
int insere (tAvl *T, int item ) {
int ok;
if (*T == NULL){ // Arvore vazia
*T = malloc(sizeof(tNo));
if (*T == NULL) return 0; //Err: mem
82
Implementao de AVLs
if ((*T )->info > item) {
//recursividade esquerda
ok = insere(&((*T )->esq), item);
if (ok != 0){
//prxima raiz a se verificar o FB
switch ((*T)->bal) {
case 1: (*T)->bal = 0;
ok = 0;
break;
case 0: (*T)->bal = -1;
break;
case -1: caso1(&(*T)); //FB(p) = -2
ok = 0;
break;
}
}
}// continua
83
Implementao de AVLs
else if ((*T )->info < item) {
//recursividade direita
ok = insere(&((*T )->dir), item);
if (ok){
switch ((*T)-> bal) {
//prxima raiz a se verificar o FB
case -1: (*T)->bal = 0;
ok = 0; break;
case 0: (*T)->bal = 1; break;
case 1: caso2(&(*T)); //FB(p) = 2
ok = 0; //no propaga mais
break;
}
}
} else
ok = 0;
return ok;
} //fim do insere
84
Implementao de AVLs
//Rotina auxiliar de insere
//Item foi inserido esquerda de T e causa
//desbalanceamento FB(T) = -2
void caso1 (tAvl *T) {
tAvl u;
u = (*T )->esq;
if (u->bal == -1)
rot_dir(&(*T)); // sinais iguais e negativo
else
rot_esq_dir(&(*T)); // sinais diferentes
(*T ) bal = 0;
}
85
Implementao de AVLs
//Rotina auxiliar de insere
//Item foi inserido direita de T e causa
//desbalanceamento FB(T) = 2
void caso2 (tAvl *T) {
tAvl u;
u = (*T )->dir;
if (u->bal == 1)
rot_esq(&(*T)); // sinais iguais e positivo
else
rot_dir_esq (&(*T)); // sinais diferentes
(*T ) bal = 0;
}
86
Implementao de AVLs
//Rotina responsvel pela rotao para a direita
void rot_dir (tAvl *T) {
tAvl u;
u = (*T )->esq;
(*T )->esq = u->dir;
u->dir = *T;
(*T )->bal = 0;
*T = u;
}
87
Implementao de AVLs
//Rotina responsvel pela rotao para a esquerda
void rot_esq (tAvl *T) {
tAvl u;
u = (*T )->dir;
(*T )->dir = u->esq;
u->esq = *T;
(*T ) bal = 0;
*T = u;
}
88
Implementao de AVLs
//Rotina que rotaciona esquerda e depois direita
void rot_esq_dir (tAvl *T) {
tAvl u,v;
u = (*T )->esq;
v = u->dir;
u->dir = v->esq;
v->esq = u;
(*T )->esq = v->dir;
v->dir = *T;
if (v->bal == -1)
(*T )->bal = 1;
else
(*T )->bal = 0;
if (v->bal == 1)
u->bal = -1;
else u->bal = 0;
*T = v;
89
}
Implementao de AVLs
//Rotina que rotaciona a direita e depois a esquerda
void rot_dir_esq (tAvl *T) {
tAvl u,v;
u = (*T )->dir;
v = u->esq;
u->esq = v->dir;
v->dir = u;
(*T )->dir = v->esq;
v->esq = *T;
if (v->bal == 1)
(*T )->bal = -1;
else (*T )->bal = 0;
if (v->bal == -1)
u->bal = 1;
else u->bal = 0;
*T = v;
}
90
Universidade Federal da Paraba
Centro de Informtica
Departamento de Informtica
Estrutura de Dados
rvores
} Tiago Maritan
} tiago@ci.ufpb.br
91