Вы находитесь на странице: 1из 7

Centro de Cincias Exatas e Sociais Aplicadas

Curso de Cincia da Computao Estrutura de Dados II Professor Andre Castro rvore


J vimos estruturas de dados que podem ser chamadas de unidimensionais ou lineares, como vetores e listas. A importncia dessas estruturas inegvel, mas elas no so adequadas para representarmos dados que devem ser dispostos de maneira hierrquica. Por exemplo, os arquivos (documentos) que criamos num computador so armazenados dentro de uma estrutura hierrquica de diretrios (pastas). Existe um diretrio base dentro do qual podemos armazenar diversos sub-diretrios e arquivos. Por sua vez, dentro dos sub-diretrios, podemos armazenar outros sub-diretrios e arquivos, e assim por diante, recursivamente.

Essas estruturas so chamadas de rvores, que so estruturas de dados adequadas para a representao de hierarquias. A forma mais natural para definirmos uma estrutura de rvores usando recursividade. Uma rvore composta por um conjunto de ns. Existe um n r, denominado raiz, que contm zero ou mais sub-rvores, cujas razes so ligadas diretamente a r. Esses ns razes das sub-rvores so ditos filhos do n pai , r. Ns com filhos so comumente chamados de ns internos e ns que no tm filhos so chamados de folhas, ou ns externos. tradicional desenhar rvores com raiz para cima e folhas para baixo, ao contrrio do que seria de se esperar. Dessa forma, no representamos explicitamente a direo dos ponteiros,

subentendendo que eles apontam sempre do pai para os filhos. O nmero de filhos permitido por n e as informaes armazenadas em cada n diferenciam os diversos tipos de rvores existentes. Por exemplo, as rvores binrias so aquelas onde cada n tem, no mximo, dois filhos. Ou as rvores ternrias possuem at trs filhos. Ou as chamadas rvores genricas, onde o nmero de filhos indefinido. Estruturas recursivas sero usadas como base para o estudo e a implementao das operaes com rvores.

rvores Binrias
Um exemplo da utilizao de rvores binrias est na avaliao de expresses. Como trabalhamos com operadores que esperam um ou dois operandos, os ns da rvore para representar um expresso tm no mximo dois filhos. Nessa rvore, os ns folhas representam operandos e os ns internos os operadores. Uma rvore que representa por exemplo a expresso ( 3 + 6 ) * ( 4 1 ) + 5 :

1/7

Centro de Cincias Exatas e Sociais Aplicadas

Curso de Cincia da Computao Estrutura de Dados II Professor Andre Castro

Numa rvore binria, cada n tem zero, um ou dois filhos. De maneira recursiva, podemos definir uma rvore binria como sendo:

Uma rvore vazia; ou Um n raiz tendo duas sub-rvores, identificadas como a sub-rvore da direita (sad) e a sub-rvore da esquerda (sae).

A figura a seguir ilustra uma estrutura de rvore binria. Os ns a, b, c, d, e, f formam uma rvore binria da seguinte maneira: a rvore composta do n a, da sub-rvore esquerda formada por b e d, e da sub-rvore direita formada por c, e e f. O n a representa a raiz da rvore e os ns b e c as razes das sub-rvores. Finalmente, os ns d, e e f so folhas da rvore.
a

Para descrever rvores binrias, podemos usar a seguinte notao textual: a rvore vazia representada por <>, e rvores no vazias por < raiz <sae><sad> >. Com essa notao, a rvore a cima representada por: < a < b <> < d <> <> > > < c < e <> <> > < f <> <> > > >

Pela definio, uma sub-rvore de uma rvore binria sempre especificada como sendo a sae ou a sad de uma rvore maior, e qualquer das duas sub-rvores pode ser vazia.

2/7

Centro de Cincias Exatas e Sociais Aplicadas

Curso de Cincia da Computao Estrutura de Dados II Professor Andre Castro


Assim, as duas rvores da figura a seguir so distintas, e podem ser vistas pela representao textual da seguinte forma respectivamente: < a < b <> <> > <> > <a <> < b <> <> > >
a a

Uma propriedade fundamental de todas as rvores que s existe um caminho da raiz para qualquer n. Com isto, podemos definir a altura de uma rvore como sendo o comprimento do caminho mais longo da raiz at uma das folhas. Assim, a altura de uma rvore com um nico n raiz zero e, por conseguinte, dizemos que a altura de uma rvore vazia negativa e vale -1. Podemos falar tambm de grau e do nvel de cada n de uma rvore. O grau representa a quantidades de filhos que um n tem. Dessa forma, em rvores binrias, o maior grau s pode ser dois. E o nvel representa a distncia do n a raiz, ou seja, o nvel da raiz zero, e os n folha mais distante da raiz a altura da rvore.

Representaes
Anlogo ao que fizemos para as demais estruturas de dados, podemos definir um tipo para representar uma rvore binria. Cada n deve armazenar trs informaes: a informao propriamente dita e dois ponteiros para as sub-rvores da esquerda e da direita. Ento a estrutura para representar o n da rvore pode ser dada por:

typedef int TInfo; typedef struct no { TInfo info; no *esq, *dir; } TNo; typedef TNo *PNo; typedef PNo TArv;

Da mesma forma que uma lista encadeada representada por um ponteiro para o primeiro n, a estrutura da rvore como um todo representada por um ponteiro para o n da raiz. Assim:

3/7

Centro de Cincias Exatas e Sociais Aplicadas

Curso de Cincia da Computao Estrutura de Dados II Professor Andre Castro

TArv arv;

Como veremos, as funes que manipulam rvores so, em geral, implementadas de forma recursiva, usando a definio recursiva da estrutura. Vamos procurar identificar e descrever apenas operaes cuja utilidade seja a mais geral possvel. Uma operao que provavelmente dever ser includa em todos os casos a inicializao de uma rvore vazia. Como uma rvore representada pelo endereo do n raiz, uma rvore vazia tem que ser representada pelo valor NULL. Assim, a rotina que inicializa uma rvore vazia pode ser:

void inicia(TArv *a) { *a = NULL; }

Uma outra rotina muito til consiste em exibir o contedo da rvore. Essa rotina deve percorrer recursivamente a rvore, visitando todos os ns e imprimindo sua informao. A implementao dessa rotina usa a definio recursiva da rvore. Vimos que uma rvore binria ou vazia ou composta pela raiz e por duas sub-rvores. Portanto, para imprimir a informao de todos os ns da rvore, devemos primeiro testar se a rvore vazia. Se no for, imprimimos a informao associada a raiz e chamamos (recursivamente) a rotina para imprimir os ns das sub-rvores.

void mostra(TArv a) { if (a != NULL) { printf("%d\n", a->info); mostra(a->esq); mostra(a->dir); } }

Uma outra operao que pode ser acrescentada a operao para liberar a memria alocada pela estrutura da rvore. Novamente, usaremos uma implementao recursiva. Um cuidado essencial a ser tomado que as sub-rvores devem ser liberadas antes de se liberar o n raiz, para que o acesso s sub-rvores no seja perdido antes de sua remoo.

4/7

Centro de Cincias Exatas e Sociais Aplicadas

Curso de Cincia da Computao Estrutura de Dados II Professor Andre Castro

void termina(TArv *a) { if (*a != NULL) { termina(&(*a)->esq); termina(&(*a)->dir); free(a); *a = NULL; } }

Ordens de Percurso em rvores Binrias


Muitas operaes em rvores binrias envolvem o percurso de todas as sub-rvores, executando alguma ao de tratamento em cada n, de forma que comum percorrer uma rvore em uma das seguintes ordens: Prordem: trata raiz, percorre sae, percorre sad; Emordem: percorre sae, trata raiz, percorre sad; Psordem: percorre sae, percorre sad, trata raiz.

rvores Binrias de Busca


So rvores que armazenam seus elementos com uma relao de ordem ( >, <, = ) entre si. Se a rvore for vazia, o elemento fica na raiz. Seno, se o elemento for menor fica na sub-rvore da esquerda, e se for maior fica na sub-rvore da direita. Dessa forma no precisamos percorrer a rvore inteira para encontrarmos um elemento. Se o elemento for menor que a raiz, precisamos procurar somente na sub-rvore da esquerda, seno somente na sub-rvore da direita.

Exerccio
Faa uma rotina para inserir um elemento em uma rvore binria de busca. Utilize o programa a seguir como base para o exerccio.

5/7

Centro de Cincias Exatas e Sociais Aplicadas

Curso de Cincia da Computao Estrutura de Dados II Professor Andre Castro

#include <stdio.h> #include <conio.h> #include <malloc.h>

typedef int TInfo; typedef struct no { TInfo info; no *esq, *dir; } TNo; typedef TNo *PNo; typedef PNo TArv;

void inicia(TArv *a) { *a = NULL; }

void imprime(TArv a, int n) { int i; if (a != NULL) { imprime(a->dir, n+5); for (i=0; i<n; i++) { printf(" "); } printf("%d\n", a->info); imprime(a->esq, n+5); } }

void mostra(TArv a) { imprime(a, 5); printf("--------------------\n"); getch(); }

void termina(TArv *a) { if (*a != NULL) { termina(&(*a)->esq); termina(&(*a)->dir); free(a); *a = NULL; } }

void insere(TArv *a, TInfo x) { }

6/7

Centro de Cincias Exatas e Sociais Aplicadas

Curso de Cincia da Computao Estrutura de Dados II Professor Andre Castro

int main() { TArv arv; inicia(&arv); mostra(arv); insere(&arv, 10); mostra(arv); insere(&arv, 5); mostra(arv); insere(&arv, 15); mostra(arv); insere(&arv, 7); mostra(arv); insere(&arv, 12); mostra(arv); insere(&arv, 3); mostra(arv); insere(&arv, 18); mostra(arv); termina(&arv); mostra(arv); return 0; }

7/7

Вам также может понравиться