Anda di halaman 1dari 26

rvores

1. Introduo
2. Definies Bsicas
3. rvores Binrias
4. Armazenamento de rvores Binrias
5. Uma Aplicao de rvores Binrias
6. Percorrendo rvores Binrias
7. O Algoritmo de Huffman
8. Removendo Ns de rvores Binrias
9. rvores Binrias Balanceadas
10. Exerccios

Introduo

Definies Bsicas
rvores so estruturas de dados extremamente teis em muitas aplicaes. Uma rvore
formada por um conjunto finito T de elementos denominados vrtices ou ns de tal
modo que se T = 0 a rvore vazia, caso contrrio temos um n especial chamado raiz
da rvore (r), e cujos elementos restantes so particionados em m>=1 conjuntos
distintos no vazios, as subrvores de r, sendo cada um destes conjuntos por sua vez
uma rvore.
A forma convencional de representar uma rvore est indicado na figura aini abaixo.
Esta rvore tem nove ns sendo A o n raiz.

Figura (aini): Uma rvore

Os conjuntos das subrvores tem de ser disjuntos tem de ser disjuntos portanto a
estrutura indicada na Figura arvn no uma rvore.

Figura arvn: Estrutura que no representa uma rvore

Se n um n da rvore T ento Tn indica uma subrvore de T com raiz no n n. Os ns


n1, n2, ..., nk das subrvores de Tn so chamados de filhos de n e n o pai destes ns, que
so ns irmos. Os ns B e C so filhos de A e ns irmos. Ns sem filhos como os ns
D, H, I, F e G so chamados de folhas. A subrvore da esquerda do n A tem raiz em B
e a subrvore da direita tem raiz em C, isto est indicado pelos dois ramos saindo de A.
A ausncia de um ramo na rvore indica uma subrvore vazia, como a subrvore da
direita do n B. O nmero de de filhos de um n chamado de grau de sada deste n.
Por exemplo, o n C tem grau de sada 3 e o n E grau 2. Se o n n a raiz de uma
subrvore Tn e n1 pertence a Tn ento n1 descendente de n e n ancestral de n1. Portanto
ns sem descendentes prprios uma folha. Por exemplo, o n H ancestral do n C e
o n D descendente do n A.
Um caminho da rvore composto por uma seqncia de ns consecutivos (n1, n2, ...,
nk-1, nk) tal que existe sempre a relao ni pai de ni+1. Os k vrtices formam k-1 pares e
um caminho de comprimento igual a k-1. O comprimento do caminho entre o n A e o
n H 3.
O nvel de um n n pode ser definido do seguinte modo: o n raiz tem nvel 0, os outros
ns tem um nvel que maior uma unidade que o nvel de seu pai. Na rvore da figura
anterior temos ns nos seguintes nveis:

nvel 0 = A
nvel 1 = B, C
nvel 2 = D, E, F, G
nvel 3 = H, I

A altura de um n n o nmero de ns do maior caminho de n at um de seus


descendentes. As folhas tem altura 1.
Existem diversas maneiras de representar rvores. Uma representao que reflete a idia
de rvores como conjuntos aninhados mostrado na figura arvconj abaixo. A figura
mostra o mesmo conjunto da figura aini.

Figura (arconj): rvore representada como conjuntos aninhados.

Uma outra notao que encontramos a toda hora, e que est representada na figura
arviden, a forma identada ou de diagrama de barras. Notar que esta representao
lembra um sumrio de livro. Os sumrios dos livros so representaes da rvore do
contedo do livro.

Figura (arviden) rvore e sua representao por barras

Uma outra forma interessante de representar uma rvore a representao por


parnteses aninhados. Da mesma forma que a figura aini representa uma rvore no
plano a representao por parnteses representa uma rvore em uma linha. A seqncia
de parnteses representa a relao entre os ns da estrutura. O rtulo do n inserido
esquerda do abre parnteses correspondente. A rvore representada planarmente pela
figura aini pode ser representada em uma linha por

(A (B(D))(C(E(H)(I))(F)(G)))
Esta representao tem importncia, por exemplo, no tratamento de expresses
aritmticas, j que toda expresso aritmtica pode ser colocada nesta forma. Se
colocarmos uma expresso nesta forma podemos ento represent-la como uma rvore,
mostrando como ela seria calculada. Para colocarmos uma expresso em forma de
rvore devemos considerar cada operador como um n da rvore e os seus operandos
como as duas subrvores. Considere a expresso C seguinte
A + (B-C)*D%(E*F)
que aps receber todos os parnteses fica da seguinte maneira
(A + ((B-C)*(D%(E*F))))

A figura arvexp mostra como fica esta expresso representada por uma rvore.

Figura (arvexp) Uma expresso e sua representao como rvore.

rvores Binrias
A figura arvbin abaixo mostra um importante tipo de rvore que a rvore binria. Em
uma rvore binria cada n tem no mximo duas subrvores, e quando h somente uma
presente necessrio distinguir entre subrvore esquerda e direita. rvores binrias
podem ser vistas em diversas situaes do cotidiano. Por exemplo, um torneio de
futebol eliminatrio, do tipo das copas dos pases, como a Copa do Brasil, em que a
cada etapa os times so agrupados dois a dois e sempre so eliminados metade dos
times uma rvore binria.

Figura abin: rvore binria


Formalmente uma rvore binria pode ser definida como um conjunto finito de ns, que
vazio, ou consiste de um n raiz e dois conjuntos disjuntos de ns, a subrvore
esquerda e a subrvore direita. importante observar que uma rvore binria no um
caso especial de rvore e sim um conceito completamente diferente. Por exemplo,
considere a figura arvbind, note que so duas rvores idnticas, mas so duas rvores
binrias diferentes. Isto porque uma delas tem a subrvore da direita vazia e a outra a
subrvore da esquerda.

Figura arcbind: rvores binrias diferentes.

Uma rvore estritamente binria uma rvore binria em que cada n tem 0 ou 2 filhos.
Uma rvore binria cheia uma rvore em que se um n tem alguma sub-rvore vazia

ento ele est no ltimo nvel. Uma rvore completa aquela em se n um n com
algumas de subrvores vazias, ento n se localiza no penltimo ou no ltimo nvel.
Portanto, toda rvore cheia completa e estritamente binria. A Figura arvbcc mostra
uma rvore estritamente binria, completa e cheia.

Armazenamento de rvores Binrias


Para armazenar cada n de uma rvore binria precisamos de uma estrutura que
contenha dois ponteiros: um aponta para a subrvore esquerda e outro para a subrvore
direita. Naturalmente, devemos ter o(s) campo(s) para armazenar as informaes que o
n deve conter. Nos algoritmos que iremos mostrar consideraremos que existe a
seguinte definio para a estrutura do n:
typedef struct sttNo {
tipo inf;
struct sttNo *esq, *dir;
} tNo;

A Figura armarv mostra um diagrama de como seria o armazenamento de uma rvore


binria. Observar que se desconsiderarmos os campos de informao para armazenar
uma rvore com n ns precisamos de 2n+1 unidades de memria.

No processo de criar uma rvore precisaremos de trs operaes importantes:


cria_arvore, pos_esq e pos_dir. cria_arvore cria uma rvore binria nova
consistindo de um nico n, armazena a informao. e retorna um ponteiro para este n.
Um algoritmo para esta funo pode ser o seguinte:
p = cria_no();
p->info = x;
p->esq = NULL;
p->dir = NULL;
return p;

pos_esq aceita um ponteiro p para uma rvore binria sem filho esquerdo e cria um
novo filho esquerdo contendo a informao x. Um possvel algoritmo para esta funo
pode ser:
if (p->left)
puts("Operao ilegal");
else {
q = cria_arvore();
p->left = q;
}

O algoritmo pos_dir semelhante a este com a diferena que ele cria um n a direita.

Uma Aplicao de rvores Binrias


As rvore binrias so estruturas importantes toda vez que uma deciso binria deve ser
tomada em algum ponto de um algoritmo. Vamos agora, antes de passar a algoritmos
mais complexos, mostrar uma aplicao simples de rvores binrias. Suponhamos que
precisamos descobrir nmeros duplicados em uma lista no ordenada de nmeros. Uma
maneira comparar cada novo nmero com todos os nmeros j lidos. Isto aumenta em
muito a complexidade do algoritmo. Outra possibilidade manter uma lista ordenada
dos nmeros e a cada nmero lido fazer uma busca na lista. Outra soluo usar uma
rvore binria para manter os nmeros. O primeiro nmero lido colocado na raiz da
rvore. Cada novo nmero lido comparado com o elemento raiz, caso seja igual uma
duplicata e voltamos a ler outro nmero. Se menor repetimos o processo com a rvore
da direita e se maior com a rvore da esquerda. Este processo continua at que uma
duplicata encontrada ou uma rvore vazia achada. Neste caso, o nmero inserido
na posio devida na rvore. Considere que os nmeros
7 8 2 5 8 3 5 10 4
foram fornecidos pelo usurio, neste caso a rvore binria mostrada na Figura arbus
seria construida.

O programa arv0300.c mostra este algoritmo. O programa insere os ns na rvore e


imprime uma mensagem caso seja fornecido um nmero que j foi lido antes.
/* programa arv0300.c */
#include<stdio.h>

#include<stdlib.h>
#include<string.h>
typedef struct stNo {
int info;
struct stNo *esq, *dir;
} tNo ;
tNo *cria_arvore( int );
tNo *cria_no( );
void pos_esq (tNo *, int );
void pos_dir (tNo *, int );
void main() {
tNo *raiz, *p, *q;
char linha[80], *numero;
int num;
gets(linha);
numero = strtok(linha, " "); /* pega o primeiro numero da lista */
num = atoi(numero);
raiz = cria_arvore(num); /* insere na raiz */
numero = strtok(NULL, " ");
while (numero) {
q = raiz; p = raiz;
printf("Li numero %d\n", num); /* le novo numero */
num = atoi(numero);
while (num != p->info && q) { /* procura na arvore */
p = q;
if (num < p->info)
q = p->esq;
/* passa para arvore esquerda */
else
q = p->dir;
/* passa para direita */
}
if (num == p->info)
printf("O numero %d ja existe na arvore.\n", num);
else { /* vou inserir o numero na arvore */
if (num < p->info)
pos_esq(p, num);
else
pos_dir(p, num);
}
numero = strtok(NULL, " ");
} /* fim do while (numero) */

tNo *cria_arvore (int x) {


tNo *p;

p = cria_no ();
if (p) {
p->info = x;
return p;
}
else {
puts("Faltou espaco para alocar no.");
exit(1);
}

tNo *cria_no() {
tNo *p;
if ((p =
return
else {
p->esq
return
}

(tNo *) malloc(sizeof(tNo))) == NULL)


NULL;
= NULL; p->dir = NULL;
p;

void pos_esq(tNo *p, int x) {


tNo *q;
if (p->esq)
puts("Operacao de insercao a esquerda ilegal.");
else {
q = cria_arvore(x);
p->esq = q;
}
}

void pos_dir(tNo *p, int x) {


tNo *q;

if (p->dir)
puts("Operacao de insercao a direita ilegal.");
else {
q = cria_arvore(x);
p->dir = q;
}

Percorrendo rvores Binrias


Uma operao muito comum percorrer uma rvore binria, o que significa passar por
todos os ns, pelo menos uma vez. O conceito de visitar significa executar uma
operao com a informao armazenada no n, por exemplo, imprimir seu contedo. Na
operao de percorrer a rvore pode-se passar por alguns ns mais de uma vez, sem
porm visit-los.
Uma rvore uma estrutura no seqncial, diferentemente de uma lista, por exemplo.
No existe ordem natural para percorrer rvores e portanto podemos escolher diferentes
maneiras de percorr-las. Ns iremos estudar trs mtodos para percorrer rvores. Todos
estes trs mtodos podem ser definidos recursivamente e se baseiam em trs operaes
bsicas: visitar a raiz, percorrer a subrvore da esquerda e percorrer a subrvore da
direita. A nica diferena entre estes mtodos a ordem em que estas operaes so
executadas.

O primeiro mtodo, conhecido como percurso em pr-ordem, implica em executar


recursivamente os trs passos na seguinte ordem.
1. Visitar a raiz;
2. Percorrer a subrvore da esquerda em pr-ordem;
3. Percorre a subrvore da direita em pr-ordem.
Para a rvore da Figura arvbinp este percurso forneceria, no caso da visita significar
imprimir, os seguintes resultados: F B A D C E H G I. Uma aplicao interessante deste
tipo de percurso aplic-lo uma rvore que contenha uma expresso aritmtica, a qual
foi expandida e recebeu todos os parnteses. Por exemplo, aplicando-se o percurso em
pr-ordem rvore arvexp obtm-se como resultado a expresso em notao polonesa
normal, isto os operandos antes dos operadores. Deste modo o resultado +A*-BC
%D*EF. Observar que esta notao diferente da notao polonesa reversa, em que os
operadores aparecem depois dos operandos.
Um algoritmo recursivo para implementar este modo de percurso pode ser o seguinte:
void pre_ordem ( tipoNo *pt) {
if (pt) {
visita (pt);
pre_ordem (pt->esq);
pre_ordem (pt->dir);
}
}

Para percorrer a rvore em ordem simtrica executa-se recursivamente os trs passos na


seguinte ordem:
1. Percorrer a subrvore da esquerda em ordem simtrica;
2. Visitar a raiz;
3. Percorrer a subrvore da direita em ordem simtrica.

Um algoritmo recursivo para implementar este modo de percurso pode ser o seguinte:
void em_ordem ( tipoNo *pt) {
if (pt) {
em_ordem (pt->esq);
visita (pt);
em_ordem (pt->dir);
}
}

Para a rvore da Figura arvbin o percurso forneceria o seguinte resultado A B C D E F G


H I.
Este tipo de percurso muito empregado em rvores binrias de busca. Considere a
rvore mostrada na Figura arvbus, que foi gerada como est indicado na seo Uma
Aplicao de rvores Binrias. Caso a rvore seja percorrida em ordem simtrica o
resultado seria
2 3 4 5 7 8 10
que so os nmeros lidos em ordem crescente sem repetio.
O percurso conhecido como ps-ordem feito a partir dos trs passos na seguinte
ordem:
1. Percorrer a subrvore da esquerda em ps-ordem;
2. Percorrer a subrvore da direita em ps-ordem;
3. Visitar a raiz;
Para a rvore da Figura arvbin o percurso forneceria o seguinte resultado A C E D B G I
H F. Um algoritmo recursivo para implementar este percurso poderia ser:
void pos_ordem(tipoNo *pt) {
if (pt) {
pos_ordem(pt->esq);
pos_ordem(pt->dir);
visita(pt);
}

O percurso em ps-ordem pode ser aplicado no clculo da altura de uma rvore. Para
calcular a altura de uma rvore necessrio calcular o maior caminho da raiz at uma de
suas folhas. Deste modo s podemos calcular o comprimento de um caminho a partir de
um n v aps percorrermos todos os seus descendentes. O algoritmo mostrado abaixo
mostra como fica a implementao da funo visita para que ela calcule a altura do
n.
void visita (tNo *p) {
int alt1, alt2;
if (p->esq) alt1 = p->esq->altura;
else alt1 = 0;
if (p->dir) alt2 = p->dir->altura;
else alt2 = 0;

if (alt1>alt2)
else p->altura
printf("info =
printf("altura

p->altura = alt1 + 1;
= alt2 + 1;
%d ", p->info);
= %d\n", p->altura);

As variveis alt1 e alt2 armazenam a altura das subrvores da esquerda e da direita e


o campo altura um novo campo da estrutura que armazena o n. A altura de um n
igual ao maior valor entre as alturas esquerda e direita incrementado de um.

Algoritmo de Huffman
Para analisarmos mais uma aplicao de rvores binrias vamos considerar o problema
de codificar uma mensagem composta de uma seqncia de smbolos de um alfabeto de
n smbolos. Esta mensagem ser transformada em uma seqncia de bits, depois de a
cada smbolo for atribudo um cdigo binrio e os cdigos dos smbolos da mensagem
forem concatenados.
Considere um alfabeto composto de quatro smbolos A, B, C e D, sendo que a cada um
dos smbolos foi atribudo o cdigo indicado a seguir:

Smbolo

Cdigo

00

01

10

11

A mensagem ABCADCA seria codificada da seguinte maneira 00011000111000, tendo


comprimento de 14 bits. O objetivo do algoritmo criar um cdigo que minimize o
comprimento da mensagem. Para criar este cdigo vamos levar em conta a freqncia
de cada smbolo na mensagem. A Tabela a seguir mostra a freqncia de cada smbolo
na mensagem

Smbolo

Freqncia

Desta tabela podemos verificar que se atribuirmos ao smbolo A um cdigo binrio mais
curto que os atribudos aos smbolos B e D teramos uma mensagem menor. Isto provm
do fato que o smbolo A aparece mais vezes do que os smbolos B e D. Suponha que os
seguintes cdigos sejam atribudos aos smbolos

Smbolo

Cdigo

110

10

111

Usando estge cdigo a mensagem ABCADCA ficaria 0110100111100 que requer 13


bits. Em mensagens longas com mais smbolos infrequentes o ganho pode ser maior.
Um dos requerimentos deste cdigo que nenhum cdigo seja prefixo de outro, caso a
decodificao seja feita da esquerda para direita.
Para decodificar a mensagem vamos comear da esquerda para a direita, caso o primeiro
bit seja 0 o cdigo corresponde ao smbolo A. No caso contrrio devemos continuar a
examinar os bits restantes. Se o segundo bit for 0 o smbolo um C, caso contrrio
examinamos o terceiro bit, um 0 indica um B e D no outro caso.
Do que vomos at agora o algoritmo para encontrar o algoritmo timo o seguinte.
Encontre os dois smbolos que aparecem com menor freqncia, no nosso caso B e D.
Atribumos 0 para B e 1 para D. Combine estes dois smbolos em um BD. Este novo
smbolo ter freqncia igual a soma das freqncias de B e D, no caso 2. Temos agora
os seguintes smbolos A (3), C (2) e BD (2), os nmeros entre parnteses so as
freqncias. Novamente devemos escolher os smbolos de menor freqncia, que so C
e BD. Atribumos o cdigo 0 ao smbolo C e 1 ao BD. Isto siginifica adicionar 1 aos
cdigos de B e D, que passam a valer 10 e 11 respectivamente. Os dois smbolos so
combinados ento no smbolo CBD de freqncia 4. Temos agora dois smbolos A (3) e
CBD (4). Atribumos 0 ao smbolo A e 1 ao smbolo CBD. O smbolo ACBD o nico
smbolo restante e recebe o cdigo NULL de comprimento 0. A Figura arvhuf1 mostra
a rvore binria que pode ser construda a partir deste exemplo. Cada n representa um
smbolo e sua freqncia.

Figura arvhuf1: rvore de Huffman


Vamos considerar outro exemplo em que temos

Removendo Ns de rvores Binrias


Para remover um n de uma rvore binria devemos considerar trs casos:
1. n sem filhos;
2. n com um unico filho;

3. n com dois filhos.


O caso de um n sem filhos o mais simples e significa apenas ajustar o ponteiro de
seu pai. A Figura remov0 ilustra este caso, onde o n com o valor 8 removido. No caso
do n ter um nico filho a mudana na rvore tambm simples significa mover o n
filho daquele ser removido uma posio para cima como est ilustrado na Figura
remove1, onde o n com o valor 6 removido. O caso mais complexo o do n com
dois filhos. Neste caso devemos procurar o sucessor s (ou antecessor) do n dever
ocupar este lugar. Este n (sucessor) um descendente que est na subrvore da direita
do n e corresponde ao n mais esquerda desta rvore. Ele no tem filhos esquerda e
a sua rvore direita pode ser movida para o lugar de s. A Figura remove2 ilustra o caso
de remoo do n com o valor 12. Observe que o n 13 (sucessor) assumiu o lugar do
n 12.

Figura remove0: Removendo n (8) sem filhos.

Figura remov1: Removendo n (6) com um filho.

Figura remov2: Removendo n (12) com dois filhos.

O texto abaixo mosta uma rotina que remove ns de uma rvore, que contm nmeros
inteiros. O programa completo est em arvremov.c.
tNo *remover (tNo *tree, int num) {
tNo *p, /* p aponta para o no a ser removido */
*q, /* q aponta para o pai do no */
*rp, /* rp aponta que ira substituir o no p */
*f,
*s; /* sucessor do no p */
p = tree; q=NULL;
/* procura o no com a chave num, p aponta para o no
e q aponta para o pai do no */
while ( p && p->info != num) {
q = p;
if ( num < p->info)
p = p->esq;
else
p = p->dir;
} /* fim do while */
if (!p) return NULL; /* a chave nao existe na arvore */

/* agora iremos ver os dois primeiros casos, o no tem um filho


no maximo */
if (p->esq == NULL)
rp = p->dir;
else
if (p->dir == NULL)
rp = p->esq;
else {
f=p;
rp = p->dir;
s = rp->esq;
/* s e sempre o filho esq de rp */
while (s != NULL) {
f = rp;
rp = s;
s = rp->esq;
}
/* neste ponto, rp e o sucessor em ordem de p */
if (f != p) {
/* p nao e o pai de rp e rp == f->left */
f->esq = rp->dir;
/* remove o no rp de sua atual posicao e o
substitui pelo filho direito de rp
rp ocupa o lugar de p
*/
rp->dir = p->dir;
}
/* define o filho esquerdo de rp de modo que rp
ocupe o lugar de p
*/
rp->esq = p->esq;
}
/* insere rp na posicao ocupada anteriormente por p */
if (q == NULL)
tree = rp;
else
if (p == q->esq)
q->esq = rp;
else
q->dir = rp;
free(p);
return rp;
}

rvores rvores Binrias Balanceadas


Uma rvore binria balanceada, chamada de rvore AVL, uma rvore binria na qual
as alturas das duas subrvores de cada um dos ns nunca diferem em mais de 1. O
balanceamento de um n igual a diferena entre as suas altura esquerda e direita.
Portanto, cada n de uma rvore balanceada tem balanceamento igual a -1, 0 ou 1,
dependendo da comparao entre as alturas esquerda e direita. Lembrando que a altura
de um n n da rvore o nmero de ns do maior caminho de n at um de seus
descendentes. As folhas tem altura 1. Uma rvore binria completa com n>0 ns tem
altura mnima, que igual a 1 + floor(log (n)). A Figura arvbal mostra uma rvore
binria balanceada. Os valores dentro do n so altura do n e seu balanceamento.

Figura arvbal: rvore binria balanceada.


Caso a probabilidade de pesquisar uma chave em uma tabela seja a mesma para todas as
chaves, uma rvore binria balanceada ter a busca mais eficiente. Infelizmente o
mtodo de insero em rvores binrias apresentado anteriormente no garante que a
rvore permanecer balanceada. Como j vimos a estrutura da rvore depende da ordem
em que as chaves so inseridas na rvore.
A Figura arvbali mostra possibilidades de insero na rvore e o que ocorreria com o
seu balanceamento. Cada insero que mantm a rvore balanceada est indicada bor
um B e as que desbalanceiam a rvore por um D. Observe que uma rvore se torna
desbalanceada quando o n inserido se torna descendente esquerdo de um n que tinha
anteriormente um balanceamento de 1 ou se ele se tornar descendente direito de um n
que tinha anteriormente balanceamento de -1. Isto fcil de deduzir, por exemplo, um
n que tinha balanceamento 1 e recebe um descendente direito aumenta sua altura em 1,
portanto aumentando o seu desbalanceamento.

Figura arvbali: rvore balanceada e suas possibilidades de insero

Observemos uma subrvore que ser tornar desbalanceada quando ocorrer uma
insero. Vamos supor tambm que este n tem um balanceamento de 1. Neste caso o
desbalanceamento ocorrer se a insero ocorrer em um n da direita. A Figura arvins
mostra um exemplo deste caso.

Figura arvins: Insero em rvore binria

Observar que o n A tem balanceamento 1, isto significa que a subrvore da esquerda


tem altura no nula e maior em uma unidade que a da direita. Ao inserirmos um n na
subrvore da direita a sua altura aumenta de um e o balanceamento passa para 2.
Observar tambm que como o n mais jovem a se tornar desbalanceado o A, o seu
filho pela esquerda tem de ter balalneamento igual a 0.
Para manter a rvore balanceada necessrio que a transformao na rvore de tal modo
que:
1. a rvore permanea uma rvore de busca binria;
2. a rvore continue a ser uma rvore balanceada.
Para isto vamos definir a operao de rotao em uma rvore. Uma rotao pode ser
direita ou esquerda. A Figura arvrot mostra uma rvore e os resultados dos dois tipos de
rotao sobre esta rvore esto mostrados na Figura arvrota.

Figura arvrot: rvore original antes da rotao

Figura arvrota: Efeitos das rotaes

Um possvel algoritmo para rodar para a esquerda uma rvore enraizada em p :


q = p->direita;
temp = q->esquerda;

q->esquerda = p;
p->direita = temp;
Para verificar o que fazer em uma rvore T aps a insero de um n q vamos
considerar os vrios casos possveis. Primeiro, se aps a incluso todos os ns se
mantiveram regulados, ento a rvore se manteve AVL e nada h a fazer. Caso contrrio
vamos considerar o n p mais prximo das folhas, que se tornou desregulado. A escolha
de p nica, pois qualquer subrvore de T que se tornou desregulada deve incluir p.
Sejam hd(p) e he(p) as alturas direita e esquerda das subrvores de p, portanto
|hd(p) - he(p)| = 2
pois T era AVL.
Temos os seguintes casos:
caso 1: hd(p) >he(p)
neste caso q pertence a subrvore esquerda de p. Alm disso p possui o filho esquerdo u
<> q, seno p no estaria desregulado. Sabe-se tambm que hd(u) <>he(u), pela mesma
razo. Para o caso 1 temos duas possibilidades:
caso 1.1

Exerccios
1. Escreva um programa que crie uma rvore de busca binria a partir de letras
lidas do teclado. O programa deve imprimir a rvore nos trs modos de percurso.
Soluo: arv0301.c
2. Faa uma funo que imprima os ns de uma rvore na sequencia de seus nveis.
Soluo: niveis.c
3. Escreva um programa que leia um arquivo que contem varios numeros inteiros
(cada numero em uma linha) e imprima os numeros em ordem crescente (utilize
uma arvore para armazenar os numeros na memoria.
Soluo: ordem.c
Este arquivo encontra-se em http://equipe.nce.ufrj.br/adriano/c/apostila/arvore.htm

Anda mungkin juga menyukai