Imprime árvore
Autor: Heitor | Publicado: 2009-11-05T00:25:00-02:00

Para ajudar a depurar os programas, fiz este código que imprime uma árvore (que não seja muito grande). Realmente ajuda bastante.Existe uma solução para grafos que se chama Graphviz./*#include "imprimeArvore.h"*/#include #include #define OK 0#define OVERFLOW 1#define UNDERFLOW -1typedef struct cel{ char info; struct cel * filhoEsq; struct cel * filhoDir;} noh;/* Esta é a estrutura de um elemento da fila */typedef struct elementoDaFila{ char info; noh *filhoEsq; noh *filhoDir; struct elementoDaFila *prox;} enfileirado;/* Funções de manipulação da fila */void copiaCampos(noh origem, enfileirado* destino){ if(destino == NULL)   fprintf(stderr, "\n\nErro: o destino da cópia é null\n\n"); else {   destino->info = origem.info;   destino->filhoEsq = origem.filhoEsq;   destino->filhoDir = origem.filhoDir; }}void copiaCampos2(enfileirado origem, noh* destino){ if(destino == NULL)   fprintf(stderr, "\n\nErro: o destino da cópia é null\n\n"); else {   destino->info = origem.info;   destino->filhoEsq = origem.filhoEsq;   destino->filhoDir = origem.filhoDir; }}void enfileira(noh novoNo, enfileirado** primeiro, enfileirado** ultimo){ enfileirado* novo = malloc(sizeof(enfileirado)); copiaCampos(novoNo, novo); if(filaVazia(*primeiro, *ultimo)) {   *primeiro = novo;   *ultimo = novo; } else {   (*ultimo)->prox = novo;   *ultimo = novo; }}int proximo(noh* devolvido, enfileirado** primeiro, enfileirado** ultimo){ if(!filaVazia(*primeiro, *ultimo)) {   copiaCampos2(**primeiro, devolvido);   if((*primeiro)->prox == NULL)     *ultimo = NULL;   *primeiro = (*primeiro)->prox;   return OK; } else {   devolvido = NULL;   return UNDERFLOW; }}int filaVazia(enfileirado* primeiro, enfileirado* ultimo){ return primeiro == NULL;}/* funções auxiliares */void imprimeVarios(char c, int quantidade){ while(quantidade > 0) {   printf("%c", c);   quantidade--; }}int maximo(int um, int outro){ if(um > outro)   return um; return outro;}int achaAltura(noh raiz){ int alturaDir; int alturaEsq; alturaDir = 0; alturaEsq = 0; if(raiz.filhoEsq != NULL)   alturaEsq = achaAltura(*(raiz.filhoEsq)); if(raiz.filhoDir != NULL)   alturaDir = achaAltura(*(raiz.filhoDir)); return maximo(alturaEsq, alturaDir) + 1;}/* só serve pra expoente não-negativo */int potencia(int base, int expoente){ if(expoente == 0) /* supondo que zero elevado a zero é 1 */   return 1; if(base == 0)   return 0; return base*potencia(base, expoente-1);}/* Função para a impressão de uma árvore binária */void imprimeArvoreBinaria(noh raiz){ int i; int nivel; /* nível atual */ int altura; int numFolhas; /* número de folhas que teria  a árvore se ela fosse cheia */ int d; /* esta variável guarda o número de folhas  que teria uma árvore cheia com altura igual  a altura da árvore - nível atual.*/ /* variáveis da fila */ enfileirado *primeiro; enfileirado *ultimo; noh *temp; noh *espaco; /* usado para "preencher" buracos na árvore, pois ela pode  não ser cheia, mas devemos ter um nó fictício no lugar*/ espaco = malloc(sizeof(noh)); espaco->info = ' '; espaco->filhoEsq = NULL; espaco->filhoDir = NULL; temp = malloc(sizeof(noh)); primeiro = NULL; ultimo = NULL; altura = achaAltura(raiz); numFolhas = potencia(2, altura-1); d = numFolhas; nivel = 1; enfileira(raiz, &amp;primeiro, &amp;ultimo); while(nivel <= altura) {   /* gambiarra's.. */   if(d == 1)     d = 0;     /* imprimindo a linha com as infos */   for(i = 0; i < potencia(2,nivel-1); i++)   {     if(proximo(temp, &amp;primeiro, &amp;ultimo) == UNDERFLOW)       fprintf(stderr, "poatz... underflow mano...");         imprimeVarios(' ', d);     if(temp->info == ' ')       imprimeVarios(' ', d-2);     else       imprimeVarios('_', d-2);     if(temp == NULL || temp->info == '\0')       printf(" ");     else       printf("%c", temp->info);     if(temp->info == ' ')       imprimeVarios(' ', d-2);     else       imprimeVarios('_', d-2);         /* se for a última iteração... */     if(i == potencia(2,nivel-1)-1)       printf("\n");     else       imprimeVarios(' ', d+3);         /* enfileirando os filhos */       if(temp->filhoEsq == NULL)       enfileira(*espaco, &amp;primeiro, &amp;ultimo);     else       enfileira(*(temp->filhoEsq), &amp;primeiro,&amp;ultimo);     if(temp->filhoDir == NULL)       enfileira(*espaco, &amp;primeiro, &amp;ultimo);     else       enfileira(*(temp->filhoDir), &amp;primeiro,&amp;ultimo);   }     /* imprimindo a linha com os "galhos" da árvores */   if(d != 0) /* gambiarra's */   {     for(i = 0; i < potencia(2,nivel-1); i++)     {       imprimeVarios(' ', d-1);       printf("/");       imprimeVarios(' ', 2*d-3);       printf("\\");             /* se for a última iteração, pula linha */       if(i == potencia(2,nivel-1)-1)         printf("\n");       else         imprimeVarios(' ', d+2);     }   }   nivel++;   d = d/2; }}int main(){ noh* varre; noh* raiz = malloc(sizeof(noh)); raiz->info = 'A'; raiz->filhoEsq = malloc(sizeof(noh)); raiz->filhoDir = malloc(sizeof(noh)); varre = raiz->filhoEsq; varre->info = 'B'; varre->filhoEsq = malloc(sizeof(noh)); varre->filhoDir = malloc(sizeof(noh)); varre = raiz->filhoDir; varre->info = 'C'; varre->filhoEsq = malloc(sizeof(noh)); varre->filhoDir = malloc(sizeof(noh)); varre = (raiz->filhoEsq)->filhoEsq; varre->info = 'D'; varre->filhoEsq = NULL; varre->filhoDir = NULL; varre = (raiz->filhoEsq)->filhoDir; varre->info = 'E'; varre->filhoEsq = NULL; varre->filhoDir = NULL; varre = (raiz->filhoDir)->filhoEsq; varre->info = 'F'; varre->filhoEsq = NULL; varre->filhoDir = NULL; varre = (raiz->filhoDir)->filhoDir; varre->info = 'G'; varre->filhoEsq = NULL; varre->filhoDir = NULL; imprimeArvoreBinaria(*raiz); return 0;}