Estruturas Árvores 05/05/2008 Aula de (parte 16: Informação 2) ÁrvoreBinária Umaárvoreemquecadanótem Umaárvorebináriaé: umaárvorevazia; a nóraizcom subárvoredadireita(sad) subárvoredaesquerda(sae) duassub-árvores: ou zero, um oudoisfilhos Fontes Livros: Introdução Bibliográficas Slides disponível Projeto Estruturas Algorithms (Szwarefiter, Cerqueira de e Algoritmos de in a Rangel): Estruturas et. C Dados (Sedgewick): al): e Capítulo (Nivio seus de Dados Algoritmos Ziviani): Capítulo 13; (Celes, rio.br/~inf1620/. baseados em http://www.inf.puc- no material da PUC-Rio, Capítulo 5; 5; ÁrvoresBinárias ImplementaçãoemC Representação: Representaçãode Estrutura A Dois inteiro) informação ponteiros em C ponteiroparao propriamente contendo para um nónaárvore: sub-árvores, dita (exemplo: nóraiz àesquerda um caractere, e àdireitaou struct arv char info; struct arv* esq; struct arv* dir; ;
TAD ÁrvoresBinárias Impl. emc (arv.h) typedef struct arv Arv; //Cria uma árvore vazia Arv* arv_criavazia (void); //cria uma árvore com a informação do nó raiz c, e //com subárvore esquerda e e subárvore direita d TAD Arv* arv_cria (char c, Arv* e, Arv* d); //libera funçãoarv_libera o espaço de memória ocupado pela árvore a Arv* (Arv* a); //retorna true se a estiver vazia e false //caso contrário int retornaumaárvorevazia, liberamemóriaalocadapelaestruturadaárvore ÁrvoresBinárias ImplementaçãoemC as raizsub-árvoresdevemser arv_vazia (Arv* a); representadapornull liberadasantes de liberaro nó //indica a ocorrência (1) ou não (0) do caracter c int arv_pertence (Arv* a, char c); //imprime informações dos nós void arv_imprime (Arv* a); Arv* arv_libera (Arv* a) if (!arv_vazia(a)) arv_libera(a->esq); /* libera sae */ arv_libera(a->dir); /* libera sad */ free(a); /* libera raiz */ return NULL; TAD funçãoarv_cria criaum retornao ÁrvoresBinárias ImplementaçãoemC a daesquerdae nóraizdadasa endereçodo a dadireita nóraizcriado informaçãoe duassub-árvores, TAD funçãoarv_vazia indicase ÁrvoresBinárias ImplementaçãoemC umaárvoreéounãovazia Arv* arv_cria (char c, Arv* sae, Arv* sad) Arv* p=(arv*)malloc(sizeof(arv)); p->info = c; p->esq = sae; p->dir = sad; return p; int arv_vazia (Arv* a) return a==null;
TAD ÁrvoresBinárias ImplementaçãoemC TAD ÁrvoresBinárias ImplementaçãoemC funçãoarv_pertence verificaa retornaum ounãodo ocorrênciade caracterenaárvore valor booleano(1 um caracterec ou0) indicandoa emum de ocorrência nós funçãoarv_imprime percorrerecursivamentea nóse imprimindosuainformação árvore, visitandotodosos Ordemde Binárias Pré-ordem: Ordemsimétrica(ouIn-Ordem): trataraiz, Percurso(outravessia) a b percorresae, d trataraiz, d a c e e f percorresad Árvores Pós-ordem: percorresae, exemplo: d b percorresad, e f c a trataraizbdaef c Ordemde Fazer In-ordem Pós-ordem Pre-ordem +*+36-415 percurso Percurso-Exercícios de Pré-ordem In-ordem Pós-ordem 3+6*4-1+5 36+41-*5+ int arv_pertence (Arv* a, char c) if (arv_vazia(a)) return 0; /* árvore vazia: não encontrou */ else return a->info==c arv_pertence(a->esq,c) arv_pertence(a->dir,c); void arv_imprime (Arv* a) if (!arv_vazia(a)) printf("%c ", a->info); /* mostra raiz */ arv_imprime(a->esq); /* mostra sae */ arv_imprime(a->dir); /* mostra sad */
Pré-Ordem Implementaçãorecursiva void arv_preordem (Arv* a) if (!arv_vazia(a)) processa(a); // por exemplo imprime Pós-Ordem Implementaçãorecursiva arv_preordem(a->esq); arv_preordem(a->dir); void arv_posordem (Arv* a) if (!arv_vazia(a)) arv_posordem (a->esq); arv_posordem (a->dir); processa (a); // por exemplo imprime In-Ordem Implementaçãorecursiva void arv_inordem (Arv* a) if (!arv_vazia(a)) arv_inordem (a->esq); Pergunta processa (a); // por exemplo imprime arv_inordem (a->dir); funçãoarv_pertence Pré-ordem, pós-ordem ou in-ordem? int arv_pertence (Arv* a, char c) if (arv_vazia(a)) return 0; /* árvore vazia: não encontrou */ else return a->info==c arv_pertence(a->esq,c) arv_pertence(a->dir,c);
Pergunta funçãoarv_libera Pré-ordem, pós-ordem ou in-ordem? ÁrvoresBinárias-conceitos Nível a o raizestáno últimoníveldaárvoreéa de um nó bnível0, seusfilhosdiretosno alturadaárvore nível nível1, 201... daecf Arv* arv_libera (Arv* a) if (!arv_vazia(a)) arv_libera(a->esq); /* libera sae */ arv_libera(a->dir); /* libera sad */ free(a); /* libera raiz */ return NULL; ÁrvoresBinárias-Altura Propriedade Alturade Esforçocomputacionalnecessárioparaalcançarqualquer Existe apenas das árvores Exemplo: nódaárvoreéproporcionalàalturadaárvore comprimentodo a folhas alturade umaárvore umaárvorecom umaárvorevaziaé-1 caminhomaislongodaraizatéumadas úniconóraizézero para nó h = 2 bdaec ÁrvoresBinárias-conceitos Árvore Cheia f todososseusnósinternostêmduassub-árvores númeron associadas = 2h+1-1de nósde umaárvorecheiade alturah
Exercícios Escrevero Utilizarpilha(definindoum topo) alocaçãodinâmicamassemutilizarprocedimentosrecursivos. parasaber algoritmode o endereçodasubárvorequerestaàdireita. visitaempré-ordemutilizando vetorquepodeser acessadopelo Escreverumafunçãorecursivaquecalculea processarraiza bináriadada. guardara seusnós. passaàb idem retornab C D depois queéa parad (topodapilha) subárvoreesquerda e napilhaparapoderacessar A processaessasubárvore alturade umaárvoreéigualaomáximonívelde paraacessaralturade Respostas int arv_altura (Arv* a) int alt_esq, alt_dir; if (arv_vazia(a)) return 0; alt_esq = arv_altura(a->esq); alt_dir = arv_altura(a->dir); return ((alt_esq>alt_dir)? alt_esq : alt_dir)+1; Respostas void arv_preordem (Arv* a) Arv* A[MAX]; //qual seria o valor de max? Arv* p; Arv* raiz; int topo; int acabou; topo = 0; p = a; acabou = arv_vazia(a); //inicializações while (!acabou) // enquanto houver nós para processar Para Fazerfunçãopararetornaro while (!arv_vazia(p)) árvore processa (p->info); Dado topo++; A[topo] = p; p = p->esq; Casopositivoretornao Pode algoritmode casa ser um recursivo item, travessia) procurase ou não conteúdodo item paide existenaárvore(usandoalgum um paido dado nónóde uma if (topo!= 0) p = A[topo]->dir; topo--; else acabou = 1;