5 de novembro de 2009

Mais percursos em árvores

Eis aqui mais alguns percursos básicos em árvores: busca em largura e versão iterativa do pré-ordem.

/**
* MAC 2301 - Laboratório de Programação
*
* Exercício extra da aula 5-b
*
* Assunto: Mais alguns percursos em árvores:
* pré-ordem iterativo
* busca em largura
*
**/

#include "pilha.h"
#include "fila.h"

void visita(noh *umNoh)
{
if(umNoh != NULL)
printf(" %c", umNoh->info);
else
printf(" [nulo]");
}

/**
* Versão não recursiva da pré-ordem
* Parecida com uma busca chamada de "busca em profundidade"
* A diferença é que na busca em profundidade, não há regras definidas
* sobre qual ramo explorar primeiro (direito ou esquerdo)
**/
void preOrdemIterativo(noh *raiz)
{
pilha p;
noh* varre;
varre = malloc(sizeof(noh));

if(raiz != NULL)
{
inicializaPilha(&p);
empilha(*raiz, &p);

while(!pilhaVazia(p))
{
desempilha(varre, &p);
visita(varre);

/* tenta empilhar filho direito */
if(varre->filhoDir != NULL)
{
if(empilha(*(varre->filhoDir), &p) != OK)
{
printf("\n\n **Erro: espaço insuficiente\n");
return;
}
}

/* tenta empilhar filho esquerdo */
if(varre->filhoEsq != NULL)
{
if(empilha(*(varre->filhoEsq), &p) != OK)
{
printf("\n\n **Erro: espaço insuficiente\n");
return;
}
}
}
}
}


/**
* Percurso em nível, cujo código é quase idêntico ao da
* pré-ordem iterativoo, apenas substituindo a pilha por uma fila
* Também conhecido como busca em largura. Não tem versão recursiva
**/
void percursoEmNivel(noh *raiz)
{
fila f;
noh* varre = malloc(sizeof(noh));

if(raiz != NULL)
{
inicializaFila(&f);
enfileira(*(raiz), &f);

while(!filaVazia(f))
{
desenfileira(varre, &f);
visita(varre);

/* tenta enfileirar o filho esquerdo */
if(varre->filhoEsq != NULL)
{
if(enfileira(*(varre->filhoEsq), &f) != OK)
{
printf("\n\n **Erro: espaço insuficiente\n");
return;
}
}

/* tenta enfileirar o filho direito */
if(varre->filhoDir != NULL)
{
if(enfileira(*(varre->filhoDir), &f) != OK)
{
printf("\n\n **Erro: espaço insuficiente\n");
return;
}
}
}
}
}

int main()
{
/**
* vamos criar a seguinte árvore:
*
______1______
/ \
__2__ __3__
/ \ / \
4 5 6 7
/ \ / \ / \ / \
8 9 A B C D E F
*
**/

noh *varre;
noh *raiz = malloc(sizeof(noh));
varre = raiz;
varre->info = '1';
varre->filhoEsq = malloc(sizeof(noh));
varre->filhoDir = malloc(sizeof(noh));

varre = varre->filhoEsq;
varre->info = '2';
varre->filhoEsq = malloc(sizeof(noh));
varre->filhoDir = malloc(sizeof(noh));

varre = varre->filhoEsq;
varre->info = '4';
varre->filhoEsq = malloc(sizeof(noh));
varre->filhoDir = malloc(sizeof(noh));

varre = varre->filhoEsq;
varre->info = '8';
varre->filhoEsq = NULL;
varre->filhoDir = NULL;

varre = ((raiz->filhoEsq)->filhoEsq)->filhoDir;
varre->info = '9';
varre->filhoEsq = NULL;
varre->filhoDir = NULL;

varre = (raiz->filhoEsq)->filhoDir;
varre->info = '5';
varre->filhoEsq = malloc(sizeof(noh));
varre->filhoDir = malloc(sizeof(noh));

varre = varre->filhoEsq;
varre->info = 'A';
varre->filhoEsq = NULL;
varre->filhoDir = NULL;

varre = ((raiz->filhoEsq)->filhoDir)->filhoDir;
varre->info = 'B';
varre->filhoEsq = NULL;
varre->filhoDir = NULL;

varre = raiz->filhoDir;
varre->info = '3';
varre->filhoEsq = malloc(sizeof(noh));
varre->filhoDir = malloc(sizeof(noh));

varre = varre->filhoEsq;
varre->info = '6';
varre->filhoEsq = malloc(sizeof(noh));
varre->filhoDir = malloc(sizeof(noh));

varre = varre->filhoEsq;
varre->info = 'C';
varre->filhoEsq = NULL;
varre->filhoDir = NULL;

varre = ((raiz->filhoDir)->filhoEsq)->filhoDir;
varre->info = 'D';
varre->filhoEsq = NULL;
varre->filhoDir = NULL;

varre = (raiz->filhoDir)->filhoDir;
varre->info = '7';
varre->filhoEsq = malloc(sizeof(noh));
varre->filhoDir = malloc(sizeof(noh));

varre = varre->filhoEsq;
varre->info = 'E';
varre->filhoEsq = NULL;
varre->filhoDir = NULL;

varre = ((raiz->filhoDir)->filhoDir)->filhoDir;
varre->info = 'F';
varre->filhoEsq = NULL;
varre->filhoDir = NULL;

/**
* Agora imprimiremos na tela dois percursos nesta árvore,
* partindo da raiz: em profundidade e em largura
**/

printf("\n\n");
printf(" Profundidade: ");
printf("\n ");

preOrdemIterativo(raiz);

printf("\n\n");
printf(" Largura: ");
printf("\n ");

percursoEmNivel(raiz);

printf("\n\n\n\n ");

system("pause");

/*
liberaArvore(raiz); // to do (por fazer)
*/

free(varre);

return 0;
}

/* arquivo base.h */

#ifndef JA_INCLUIU_ESTA_BASE

#include
#include

#define JA_INCLUIU_ESTA_BASE 1
#define OVERFLOW 1
#define UNDERFLOW -1
#define OK 0
#define MAX 100

typedef struct node
{
char info;
struct node *filhoEsq;
struct node *filhoDir;
} noh;

/* arquivo fila.h */

#include "base.h"

typedef struct queue
{
int primeiro;
int ultimo;
noh f[MAX];
} fila;

/**
* função booleana que devolve um valor diferente
* de zero se a fila está vazia e zero c.c.
**/
int filaVazia(fila sobInvestigacao);

void inicializaFila(fila *umaFila);

int enfileira(noh novo, fila *umaFila);

/* arquivo pilha.h */

#include "base.h"

typedef struct stack
{
int topo;
noh p[MAX];
} pilha;

/**
* função booleana que devolve um valor diferente
* de zero se a pilha está vazia e zero c.c.
**/
int pilhaVazia(pilha sobInvestigacao);

void inicializaPilha(pilha *umaPilha);

int empilha(noh novo, pilha *umaPilha);

/* arquivo fila.c */

#include "fila.h"

/**
* função booleana que devolve um valor diferente
* de zero se a fila está vazia e zero c.c.
**/
int filaVazia(fila sobInvestigacao)
{
return (sobInvestigacao.primeiro == -1 &&
sobInvestigacao.ultimo == -1);
}

void inicializaFila(fila *umaFila)
{
if(umaFila == NULL)
umaFila = malloc(sizeof(fila));
umaFila->primeiro = -1;
umaFila->ultimo = -1;
}

int enfileira(noh novo, fila *umaFila)
{
int temp;
if(filaVazia(*umaFila))
{
umaFila->primeiro = 0;
umaFila->ultimo = 0;
umaFila->f[0] = novo;
return OK;
}
else
{
temp = (umaFila->ultimo + 1) % MAX;
if(temp == umaFila->primeiro)
return OVERFLOW;
else
{
umaFila->ultimo = temp;
umaFila->f[temp] = novo;
return OK;
}
}
}

int desenfileira(noh *desenfileirado, fila *umaFila)
{
if(filaVazia(*umaFila))
return UNDERFLOW;
else
{
*desenfileirado = (umaFila->f)[umaFila->primeiro];
if(umaFila->primeiro == umaFila->ultimo)
{
inicializaFila(umaFila);
}
else
umaFila->primeiro = (umaFila->primeiro +1) % MAX ;
return OK;
}
}


/* arquivo pilha.c */
#include "pilha.h"

/**
* função booleana que devolve um valor diferente
* de zero se a pilha está vazia e zero c.c.
**/
int pilhaVazia(pilha sobInvestigacao)
{
return (sobInvestigacao.topo == 0);
}

void inicializaPilha(pilha *umaPilha)
{
if(umaPilha == NULL)
umaPilha = malloc(sizeof(pilha));
umaPilha->topo = 0;
}

int empilha(noh novo, pilha *umaPilha)
{
if(umaPilha != NULL)
{
if(umaPilha->topo == MAX)
return OVERFLOW;
else
{
(umaPilha->p)[umaPilha->topo] = novo;
(umaPilha->topo)++;
return OK;
}
}
else
return OVERFLOW;
}

int desempilha(noh *desempilhado, pilha *umaPilha)
{
if(umaPilha != NULL)
{
if(umaPilha->topo == 0)
return UNDERFLOW;
else
{
(umaPilha->topo)--;
*desempilhado = (umaPilha->p)[umaPilha->topo];
return OK;
}
}
else
return UNDERFLOW;
}



int desempilha(noh *desempilhado, pilha *umaPilha);


int desenfileira(noh *desenfileirado, fila *umaFila);

#endif

Nenhum comentário:

Postar um comentário